In the Unity learn section - survival shooter, I am getting an error shows the following error
Type "UnityEngine.Animation" does not contain a definition for "SetBool" and no extension method "SetBool" of type "UnityEngine.Animation" could be found. Are you missing an assembly reference?
I have checked the name of files and components.
Code
using UnityEngine;
public class PlayerMovement: MonoBehaviour
{
public float speed = 6f;
Vector3 movement;
Animation anim;
Rigidbody playerRigidbody;
int floorMask;
float camRayLength = 100f;
void Awake()
{
floorMask = LayerMask.GetMask("Floor");
anim = GetComponent<Animation>();
playerRigidbody = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Verticle");
Move(h, v);
Turning();
Animating(h, v);
}
void Move(float h, float v)
{
movement.Set(h, 0f, v);
movement = movement.normalized * speed * Time.deltaTime;
playerRigidbody.MovePosition(transform.position + movement);
}
void Turning()
{
Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit floorHit;
if(Physics.Raycast (camRay ,out floorHit, camRayLength, floorMask))
{
Vector3 playerToMouse = floorHit.point - transform.position;
playerToMouse.y = 0f;
Quaternion newRotation = Quaternion.LookRotation(playerToMouse);
playerRigidbody.MoveRotation (newRotation);
}
}
void Animating(float h, float v)
{
bool walking = h!= 0f || v!= 0f;
anim.SetBool("IsWalking", walking);
}
}
The character's animation controller is of type Animator, not Animation. Use SetBool on Animator.
Animator anim;
void Awake()
{
// ...
anim = GetComponent<Animator>();
// ...
}
Related
I'm creating a simple movement/following script in C#. I have a prefab (ball) spawn randomly within the Awake() method, at a random area in my scene. I then have another script attached to a different game object (robot) that at the start of the game shall move towards the ball.
Now the movement works but when the game object has come into the the minDistanceToTarget it begins to "jitter" and move around.
Here's the movement script:
public class RobotMovement : MonoBehaviour {
// Movement
private Transform target;
private float speed = 2f;
private float distance;
private float minDistanceToTarget = 1f;
// Rotation
private Vector3 targetDirection;
private Quaternion lookAtRotation;
private float RotationSpeed = 2f;
void Start() {
target = GameObject.FindGameObjectWithTag("Ball").transform;
}
void Update() {
targetDirection = target.position - transform.position;
lookAtRotation = Quaternion.LookRotation(targetDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, lookAtRotation, RotationSpeed * Time.deltaTime);
distance = Vector3.Distance(transform.position, target.position);
if (distance >= minDistanceToTarget) {
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
}
}
Edit I tried to change the affect to use FixedUpdate and affect the RigidBodies instead.
public class RobotMovement : MonoBehaviour {
private Rigidbody robot;
public Rigidbody target;
// Movement
private float speed = 2f;
private float minDistanceToTarget = 2f;
void Start() {
robot = GetComponent<Rigidbody>();
target = target.GetComponent<Rigidbody>();
}
void FixedUpdate() {
if (Vector3.Distance(robot.position, target.position) > minDistanceToTarget) {
robot.MovePosition(target.position * speed * Time.deltaTime);
}
}
}
Edit I now use a new movement method and include a rotation calculation. But it still jumps and jitters
public class RobotMovement : MonoBehaviour {
private Rigidbody robot;
private Transform ball;
// Movement
private float robotMovSpeed = 2f;
private float distanceToTarget;
private float distanceToStop = 2f;
// Rotation
private Vector3 targetDirection;
private Quaternion lookAtTarget;
private float rotationSpeed = 2f;
void Start() {
robot = GetComponent<Rigidbody>();
ball = GameObject.FindGameObjectWithTag("Ball").transform;
}
void FollowTarget(Transform target, float distanceToStop, float speed) {
distanceToTarget = Vector3.Distance(robot.position, target.position);
// Rotation
targetDirection = target.position - robot.position;
lookAtTarget = Quaternion.LookRotation(targetDirection);
if (distanceToTarget >= distanceToStop) {
transform.rotation = Quaternion.Slerp(transform.rotation, lookAtTarget, rotationSpeed * Time.deltaTime);
robot.MovePosition(robot.position + (target.position - robot.position).normalized * speed * Time.deltaTime);
}
}
void FixedUpdate() {
FollowTarget(ball, distanceToStop, robotMovSpeed);
}
}
Here's my code. Currently, the player moves forwards relative to a fix plane. Rotating the player/camera has no affect on which direction they travel when I press the "go forward" key.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MainController : MonoBehaviour
{
public float speed;
float jumpSpeed = 0.5f;
bool isGrounded;
private Rigidbody rb;
public GameObject player;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
}
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
if (Input.GetButtonDown("Jump") || Input.GetAxis("Right Trigger") > 0f && isGrounded)
{
rb.AddForce(Vector3.up * jumpSpeed, ForceMode.Impulse);
isGrounded = false;
}
if (isGrounded)
{
rb.AddForce(movement * speed * Time.deltaTime);
}
else
{
rb.AddForce((movement/4) * speed * Time.deltaTime);
}
}
void OnCollisionStay()
{
isGrounded = true;
}
void OnCollisionExit()
{
isGrounded = false;
}
}
How do I make it so that the player moves relative to the camera's direction?
It's because RigidBody.AddForce() adds force in absolute direction, no matter which direction the gameobject is looking.
You should try using RigidBody.AddRelativeForce(), like:
if (isGrounded)
{
rb.AddRelativeForce(movement * speed * Time.deltaTime);
}
I think there is a better way to do this, but see if it results in the expected behavior:
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 looking = (transform.rotation * Vector3.forward).normalized;
Vector3 perpendicular = Vector2.Perpendicular(new Vector2(looking.x, looking.z));
perpendicular.z = perpendicular.y;
perpendicular.y = looking.y;
Vector3 vertical = moveVertical * looking;
Vector3 horizontal = moveHorizontal * perpendicular;
Vector3 movement = vertical - horizontal;
...
}
How can I have my enemy disable a script once it reaches target player? I want to reference this script called casting under my GameManager in my code and disable it but I'm unsure how to write the function for when target location is reached.
public float lookRadius = 40f;
Transform target;
UnityEngine.AI.NavMeshAgent agent;
Rigidbody theRigidBody;
void Start()
{
target = PlayerManager.instance.player.transform;
agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
}
void Update()
{
float distance = Vector3.Distance (target.position, transform.position);
if (distance <= lookRadius)
{
agent.SetDestination (target.position);
if (distance <= agent.stoppingDistance)
{
FaceTarget ();
}
}
}
void FaceTarget()
{
Vector3 direction = (target.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation (new Vector3 (direction.x, 0, direction.z));
transform.rotation = Quaternion.Slerp (transform.rotation, lookRotation, Time.deltaTime * 5f);
}
// Use this for initialization
public void OnObjectSpawn ()
{
//myRender = GetComponent<Renderer> ();
theRigidBody = GetComponent<Rigidbody>();
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere (transform.position, lookRadius);
}
You need to obtain the gameobject that has the script, get the script on that gameobject, and disable.
if (distance < 1f) // or some distance
{
Gameobject mygo = GameObject.Find("GameManager"); // or some other method to get gameobject.
mygo.GetComponent<casting>().enabled = false;
}
I am learning Unity Game development .. I was following https://unity3d.com/learn/tutorials/projects/survival-shooter/player-character?playlist=17144
Did everything same but,
I want the player object to rotate towards the mouse pointer. But it's not rotating towards mouse pointer..
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
Vector3 movement;
Animator anim;
Rigidbody playerRigidbody;
int floormask;
float camraylength = 100f;
float speed = 10f;
void Awake()
{
anim = GetComponent<Animator>();
floormask = LayerMask.GetMask("floor");
playerRigidbody = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
moving(h, v);
tunning();
animationz(h, v);
}
void moving(float h, float v)
{
movement = new Vector3(h, 0, v);
movement = movement.normalized * speed * Time.deltaTime;
playerRigidbody.MovePosition(transform.position + movement);
}
void tunning()
{
Ray camray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit floorhit;
if(Physics.Raycast(camray,out floorhit, camraylength, floormask))
{
Vector3 playertomouse = floorhit.point - transform.position;
playertomouse.y = 0f;
Quaternion newrotate = Quaternion.LookRotation(playertomouse);
playerRigidbody.MoveRotation(newrotate);
}
}
void animationz(float h, float v)
{
bool walking = h != 0f || v != 0f;
anim.SetBool("IsWalking", walking);
}
}
The tunning() method is in the above code
If anything more you want then please comment. Thank you for the help...
I suggest you check several stuff to find the source of the problem:
You need to make sure you are using a Quad not a Plane and that the correct face is upwards
Make sure the layer of the quad is "floor" (it's case sensitive)
Make sure the camera is not further than the 100f of the ray you are casting
And finally add a Debug.Log() inside the if condition to check if the ray hits the floor at all.
I am messing around in Unity and wanted to make a mechanic where a box would touch another object and then that object would follow the Player.
I have Cube set up like this:
And a Sphere with a Box Collider with same options.
My Player script is thus:
public class Player : MonoBehaviour {
public float speed = 0.0f;
public float moveX = 0.0f;
public float moveY = 0.0f;
public GameObject player;
public GameObject obj;
//public float force = 0.0f;
private bool collided = false;
// Use this for initialization
void Start () {
player = GameObject.FindWithTag ("Player");
}
// Update is called once per frame
void FixedUpdate () {
moveX = Input.GetAxis ("Horizontal");
moveY = Input.GetAxis ("Vertical");
player.GetComponent<Rigidbody> ().velocity = new Vector2 (moveX * speed, moveY * speed);
}
void OnCollisionEnter (Collision col) {
if (col.gameObject == obj) {
collided = true;
}
}
void OnCollisionExit (Collision col) {
if (col.gameObject == obj) {
collided = false;
}
}
void Update () {
if(collided) {
obj.transform.position = (player.transform.position - obj.transform.position)*speed;
}
}
}
What have I yet to do? Hoping someone can nudge me in the right direction.
I will provide you two scripts.
1st Script is FollowTarget. This will follow your target forcely.
2nd Script is SmoothFollow which will follow your target in a smooth movement.
FollowTarget.cs
using System;
using UnityEngine;
public class FollowTarget : MonoBehaviour
{
public Transform target;
public Vector3 offset = new Vector3(0f, 7.5f, 0f);
private void LateUpdate()
{
transform.position = target.position + offset;
}
}
SmoothFollow.cs
using UnityEngine;
public class SmoothFollow : MonoBehaviour
{
// The target we are following
[SerializeField]
private Transform target;
// The distance in the x-z plane to the target
[SerializeField]
private float distance = 10.0f;
// the height we want the camera to be above the target
[SerializeField]
private float height = 5.0f;
[SerializeField]
private float rotationDamping;
[SerializeField]
private float heightDamping;
// Use this for initialization
void Start() { }
// Update is called once per frame
void LateUpdate()
{
// Early out if we don't have a target
if (!target)
return;
// Calculate the current rotation angles
var wantedRotationAngle = target.eulerAngles.y;
var wantedHeight = target.position.y + height;
var currentRotationAngle = transform.eulerAngles.y;
var currentHeight = transform.position.y;
// Damp the rotation around the y-axis
currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
// Damp the height
currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);
// Convert the angle into a rotation
var currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);
// Set the position of the camera on the x-z plane to:
// distance meters behind the target
transform.position = target.position;
transform.position -= currentRotation * Vector3.forward * distance;
// Set the height of the camera
transform.position = new Vector3(transform.position.x ,currentHeight , transform.position.z);
// Always look at the target
transform.LookAt(target);
}
}
Just choose one of them and then attach it to the gameObject. Like another box that is suppose to follow.
Remove your Update() function in your script as you don't need it anymore.
Also Remove your OnCollisionExit()
void OnCollisionEnter (Collision col) {
if (col.gameObject == obj) {
// If you choose to use SmoothFollow Uncomment this.
//col.GetComponent<SmoothFollow>().target = this.transform;
// If you choose to use FollowTarget Uncomment this
//col.GetComponent<FollowTarget>().target = this.transform;
}
}