I've managed to make a little top down shooter now I'm going over animations. I have followed a couple tutorials by pixelnest.io but strangly I'm getting an error saying "parameter 'moveRight' does not exist. animation in unity is completely new to me and have been trying to read up as much as I can. any suggestions to fix the animation so it plays when I move right? below are some pictures and my code.
using UnityEngine;
using System.Collections;
public class playerMove : MonoBehaviour {
public float maxSpeed = 5f;
Animator animator;
bool isRight;
void Awake(){
animator = GetComponent<Animator>();
}
void Update(){
Vector3 posMove = transform.position;
Vector3 velocityH = new Vector3 (Input.GetAxis ("Horizontal") * maxSpeed * Time.deltaTime, 0, 0);
//this is just test a before i add it to the right movement
animator.SetBool ("moveRight", isRight);
Vector3 velocityV = new Vector3 (0, Input.GetAxis ("Vertical") * maxSpeed * Time.deltaTime, 0);
posMove += velocityH + velocityV;
transform.position = posMove;
}
}
This is because you don't have a boolean called "moveRight" in your animator.
Look at the first screenshot you posted. In the bottom left corner, you've declared a single boolean named "isRight".
While using Animator.SetBool(yourBool, boolValue), you first parameter you need to pass is the name of the boolean declared in the animator (in this case, it's "isRight").
Change the following line of code in your script
Change this line
animator.SetBool ("moveRight", isRight);
to read
animator.SetBool ("isRight", isRight);
Related
I have a virtual movement joystick that I'm using to control the movement of a player object which works fine, the code for this is below.
The problem I have is when I rotate the camera within game mode (or device) the direction is not adjusted according to the cameras rotation, exactly like is shown in this post here that I looked through to try and understand the problem.
I realise I need to rotate my movement around the forward direction the camera is facing which I tried to do with the bottom snippet of code however this yields really strange behavior when the player object moves incredibly fast and eventually unity becomes unresponsive, so something is being incorrectly multiplied I guess.
Could anybody point out where I'm going wrong please? ta !
Edit - Modified to potential answer
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using EasyJoystick;
public class NewJoystick : MonoBehaviour
{
[SerializeField] private float speed;
[SerializeField] private Joystick1 joystick;
[SerializeField] Camera MainCam;
private Rigidbody RB;
private Transform cameraTransform;
// Start is called before the first frame update
void Start()
{
cameraTransform = MainCam.transform;
}
void Awake()
{
RB = gameObject.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
float xMovement = joystick.Horizontal();
float zMovement = joystick.Vertical();
Vector3 inputDirection = new Vector3(xMovement, 0, zMovement);
//Get the camera horizontal rotation
Vector3 faceDirection = new Vector3(cameraTransform.forward.x, 0, cameraTransform.forward.z);
//Get the angle between world forward and camera
float cameraAngle = Vector3.SignedAngle(Vector3.forward, faceDirection, Vector3.up);
//Finally rotate the input direction horizontally by the cameraAngle
Vector3 moveDirection = Quaternion.Euler(0, cameraAngle, 0) * inputDirection;
RB.velocity = moveDirection * speed;
}
}
I tried this in the update loop -
var Direction = transform.position += new Vector3(xMovement, 0f,zMovement); //* speed * Time.deltaTime;
Vector3 newDir = MainCam.transform.TransformDirection(Direction);
transform.position += new Vector3(newDir.x, 0f,newDir.z) * speed * Time.deltaTime;
Well, here is a simple idea for how to solve it. At least this is how I did it, and it seems to work ever since.
First, you need to get the joystick input, like you did. Both axis input value should be between -1 and 1. This actually determines the direction itself, since the horizontal axis gives you the X coordinate of a vector and the vertical gives you the Y coordinate of that vector. You can visualize it easily:
Mind, that I just put up some random values there, but you get the idea.
Now, your problem is, that this angle you get from your raw input is
static in direction, meaning that it doesn't rely on the camera's face
direction. You can solve this problem by "locking it to the camera",
or in other words, rotate the input direction based on the camera
rotation. Here's a quick example:
//Get the input direction
float inputX = joystick.Horizontal();
float inputY = joystick.Vertical();
Vector3 inputDirection = new Vector3(inputX, 0, inputY);
//Get the camera horizontal rotation
Vector3 faceDirection = new Vector3(cameraTransform.forward.x, 0, cameraTransform.forward.z);
//Get the angle between world forward and camera
float cameraAngle = Vector3.SignedAngle(Vector3.forward, faceDirection, Vector3.up);
//Finally rotate the input direction horizontally by the cameraAngle
Vector3 moveDirection = Quaternion.Euler(0, cameraAngle, 0) * inputDirection;
IMPORTANT: The code above should be called in the Update cycle, since that is where you get the input information.
After this, you can work with moveDirection to move your player. (I suggest using physics for moving, instead of modifying its position)
Simple moving example:
public RigidBody rigidbody;
public Vector3 moveDirection;
public float moveSpeed = 5f;
void FixedUpdate()
{
rigidbody.velocity = moveDirection * moveSpeed;
}
I'm a Unity beginner.
I have a problem with my script: in the picture above, Player item does not exist in Move script.
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public float speed;
public Transform player;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
transform.Translate(x * speed * Time.deltaTime, y * speed * Time.deltaTime, 0);
Vector2 v2 = Camera.main.ScreenToWorldPoint(Input.mousePosition) - player.position;
player.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(v2.y, v2.x) * Mathf.Red2Deg);
}
}
I am not sure if I understand you right, but as this script is the script that belongs to the Player Gameobject, you don't need to specify "public Transform player".
The Gameobject class inherits from the Transform class, so it should work if you try:
Vector2 v2 = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(v2.y, v2.x) * Mathf.Red2Deg);
Maybe to make it more clear:
You don't need to have Player as an "item" that you pull into the according field in the inspector as it was the case if you relate to a gameobject which does not contain the "Move" script.
So, if you attach a script to a gameobject (in this case you attach the script to "Player"), then any methods you script, are directly affecting the gameobject the script belongs to.
E.g. try the following:
void Update() {
if(Input.GetKeyDown("space")) {
Destroy(gameObject);
}
}
You will see that the circle, which forms your player, will destroy itself when you hit the space bar. The parameter "gameObject" refers to the gameobject the script belongs to.
I hope that helps you to understand that you don't need to specify an extra GameObject that needs to be linked to the script, as long as the Gameobject you want to manipulate contains this script.
Basically, when I have my cursor in the center of the screen, the camera doesn't rotate. Pretty standard. However, If I move my cursor to the left or right, It will start rotating. Still makes sense. However, When I stop moving the cursor, the rotation continues. I'm using an empty object and making the camera face in the same direction as that empty object. The problem is, the object continues to rotate. If I move the cursor back to the center of the screen, it stops rotating again. Something similar happens when I assign axes in the project settings to the right stick on an Xbox 1 controller. If I move the stick right, the camera begins to rotate, however, if I return the stick to the deadzone, it continues to rotate. If I then move the stick left, it will slow down the rotation, and eventually begin rotating the other direction. It doesn't happen with the vertical stick axis, though.
Here's my code with the mouse for the player and empty object rotation:
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public Transform PlayerT;
public Transform camT;
public Transform CamR;
public CharacterController controller;
public float speed;
public float CamRSpeed;
private float gravity;
private float HorizontalR;
private float VerticalR;
private Vector3 moveDirection;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
HorizontalR = Input.GetAxis("Mouse X") * CamRSpeed * Time.deltaTime;
VerticalR = Input.GetAxis("Mouse Y") * CamRSpeed * Time.deltaTime;
CamR.Rotate(VerticalR, HorizontalR, 0f);
PlayerT.forward = CamR.forward;
PlayerT.eulerAngles = new Vector3(0f, PlayerT.eulerAngles.y, 0f);
moveDirection = (PlayerT.forward * Input.GetAxis("Vertical") * speed) + (PlayerT.right * Input.GetAxis("Horizontal") * speed);
controller.Move(moveDirection * Time.deltaTime);
}
}
//and for the camera (this is a separate script, I'm just not entirely sure how this site's formatting works):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraScript : MonoBehaviour
{
public Transform cam;
public Transform player;
public Transform CamR;
private Vector3 offset;
// Start is called before the first frame update
void Start()
{
offset = CamR.position - cam.position;
}
// Update is called once per frame
void Update()
{
cam.eulerAngles = new Vector3(CamR.eulerAngles.x, CamR.eulerAngles.y, 0f);
cam.position = CamR.position - (CamR.rotation * offset);
}
}```
Well, as it turns out, it was simply because the object I was trying to rotate was a child of the player. I'm not entirely sure why it didn't work, but it does now.
I have been trying this for two days with no success. I cant figure out where I'm missing the point. All the missiles are moving towards the position of the target but not following it. The position remains fixed and all the newly created missiles come to this point instead of following the target.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HomingMissile : MonoBehaviour
{
private GameObject target; //changed to private
private Rigidbody rb;
public float rotationSpeed;
public float speed;
Quaternion rotateToTarget;
Vector3 direction;
private void Start()
{
target = GameObject.FindGameObjectWithTag("Player"); //uncommented this
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
//made some modifications
Vector3 direction = (target.transform.position - transform.position).normalized;
float angle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;//interchanged x and z
Quaternion rotateToTarget = Quaternion.Euler(0, angle, 0);
transform.rotation = Quaternion.Slerp(transform.rotation, rotateToTarget, Time.deltaTime * rotationSpeed);
Vector3 deltaPosition = speed * direction * Time.deltaTime;
rb.MovePosition(transform.position + deltaPosition);
}
}
I selected the target(transform) using the inspector.
I'm using Unity and C# obviously you know that.
What Im trying to achieve is that the missile should follow the position of the target in real time. And i can add the destroy code for the missile myself.
Note :
Please don't tag this as a duplicate. It is not.
The game is 2D where Y is always constant. Vertical axis is X and Horizontal axis is X. The objects are 3D. That's why I can't use rigidbody2D.
EDIT:
Code edited. The missile follows the target and also points to the direction of motion. How to make the missile make a circular rotation when it needs to rotate?
Firstly, consider:
Not modifying a rigidbody.velocity directly, as it will result in unrealistic behaviour
Using FixedUpdate() instead of Update() when controlling rigidbodies
Use rigidbody.movePosition() and rigidbody.moveRotation() instead. Here's an example:
Vector3 dir = (target.transform.position - transform.position).normalized;
Vector3 deltaPosition = speed * dir * Time.deltaTime;
rb.MovePosition(transform.position + deltaPosition);
Try out rigidbody.MoveRotation() yourself for practice.
Finally, understand that there are many ways to implement homing for missiles. Here's one that is commonly used in real life.
Edit: I will not recommend using rb.addForce() because if u try it out u will realise it is too indeterministic.
When reading this, keep in mind I'm new to both programming and Unity, so I might be missing some terms or tools Unity offer. Please elaborate your answers in an ELI5 manner. Thanks in advance!
I am currently working on some game-physics for a small personal project. Currently I've created a platform, a character and what should be, a following companion.
However, since I'm still not on a level, where I can create perfect code on own hand, I found an "enemy" script and tried to modify it a bit.
It Works to an extend, but it needs some tweaks which I hope I can help aquire with you guys.
This is how it looks now (the orange square is the companion)
It follows the player, and I can tweak the speed to fit as a companion, and not a player. However, as the Picture presents, the companion runs for the center of the player. What I want to create is a companion which follows the player, but still keeps a small gap from the player.
My first thoughts was to create some kind of permanent offset, but I fail to figure out how to do this without messing up the follow function.
I hope you can help me, it will be much appreciated!
Here's the code for reference.
Code attached to Player:
using UnityEngine;
using System.Collections;
public class PlayerCompanion : MonoBehaviour
{
//In the editor, add your wayPoint gameobject to the script.
public GameObject wayPoint;
//This is how often your waypoint's position will update to the player's position
private float timer = 0.5f;
void Update ()
{
if (timer > 0) {
timer -= Time.deltaTime;
}
if (timer <= 0) {
//The position of the waypoint will update to the player's position
UpdatePosition ();
timer = 0.5f;
}
}
void UpdatePosition ()
{
//The wayPoint's position will now be the player's current position.
wayPoint.transform.position = transform.position;
}
}
Code attached to companion:
using UnityEngine;
using System.Collections;
public class FollowerOffset : MonoBehaviour {
//You may consider adding a rigid body to the zombie for accurate physics simulation
private GameObject wayPoint;
private Vector3 wayPointPos;
//This will be the zombie's speed. Adjust as necessary.
private float speed = 10.0f;
void Start ()
{
//At the start of the game, the zombies will find the gameobject called wayPoint.
wayPoint = GameObject.Find("wayPoint");
}
void Update ()
{
wayPointPos = new Vector3(wayPoint.transform.position.x, transform.position.y, wayPoint.transform.position.z);
//Here, the zombie's will follow the waypoint.
transform.position = Vector3.MoveTowards(transform.position, wayPointPos, speed * Time.deltaTime);
}
}
bump, I guess ? :)
You can use smooth follow script. I have created a sample class for you. This class has features to follow any given gameobject with some delay and offset. You will have to tweak some values according to your need.
using UnityEngine;
using System.Collections;
public class PlayerCompanion : MonoBehaviour
{
[SerializeField]
private GameObject wayPoint;
[SerializeField]
public Vector3 offset;
public Vector3 targetPos;//Edit: I forgot to declare this on firt time
public float interpVelocity;
public float cameraLerpTime = .1f;
public float followStrength = 15f;
// Use this for initialization
void Start ()
{
//At the start of the game, the zombies will find the gameobject called wayPoint.
wayPoint = GameObject.Find("wayPoint");
offset = new Vector3 (5,0,0);//input amount of offset you need
}
void FixedUpdate () {
if (wayPoint) {
Vector3 posNoZ = transform.position;
Vector3 targetDirection = (wayPoint.transform.position - posNoZ);
interpVelocity = targetDirection.magnitude * followStrength;
targetPos = transform.position + (targetDirection.normalized * interpVelocity * Time.deltaTime);
transform.position = Vector3.Lerp (transform.position, targetPos + offset, cameraLerpTime);
}
}
}
Attach this class to your player companion, play with different values.
To preserve object orientation your companion schould not be anyways child of your main character.
Your wayPoint doesn't needs to be a GameObject but a Transform instead and your code will looks like better.
If your game is a 2D platform your and your companion needs to be backwards your player it probabli applys to just one axis (X?) so you can decrement your waiPoint in a more directly way by calculating it on your UpdatePosition function like this:
wayPoint.position = transform.position * (Vector3.left * distance);
where your "distance" could be a public float to easily setup.
so on your companion script Update just do:
transform.position = Vector3.MoveTowards(transform.position, wayPoint.position, speed * Time.deltaTime);
I can't test it right now so you could have problems with Vector3 multiply operations, just comment and I'll try to fix as possible ;)