My character moves only to the left without me doing anything - c#

My character moves by itself without me doing anything, I have already reviewed the movement code several times, I even tried trying other methods with the same function (moving the character) and they all continued with the same problem (The code worked in yes, but my character moves infinitely by itself) I also installed and uninstalled versions of unity client to see if it could be solved by doing that but no
Do you think it could be a problem with the unity client? I am using version 2022 although in version 2021 and 2019 the same thing happened to me, could it be some configuration that I touched by accident? And if so, how do I return it to its original state?
Here is one of the codes I used, I also tried with CharacterController
public class PlayerController : MonoBehaviour
{
private new Rigidbody rigidbody;
public float speed = 10f;
void Start()
{
rigidbody = GetComponent<Rigidbody>();
}
void Update()
{
float hor = Input.GetAxisRaw("Horizontal");
float ver = Input.GetAxisRaw("Vertical");
if (hor != 0.0f || ver != 0.0f)
{
Vector3 dir = transform.forward * ver + transform.right * hor;
rigidbody.MovePosition(transform.position + dir * speed * Time.deltaTime);
}
}
}
And this is other script i tried using CharacterController
public class PlayerController : MonoBehaviour {
public float horizontalMove;
public float verticalMove;
public CharacterController player;
public float playerspeed;
void Start() {
player = GetComponent<CharacterController>();
}
void Update() {
horizontalMove = Input.GetAxis("Horizontal");
verticalMove = Input.GetAxis("Vertical");
}
private void FixedUpdate()
{
player.Move(new Vector3(horizontalMove, 0, verticalMove) * playerspeed * Time.deltaTime);
}
}
I used when I saw that they did not solve the problem, I saved and deleted from my project, right now I created a new file to focus on finding solutions to the problem, since with any script to move the character this happens to me with rigidbody or CharacterController
I tried using the Debug.Log to find out if what was the problem but it didn't work either
It sits on flat ground, I also turned gravity off but the problem was still working. No external forces are applied to the rigid body as it is a new project I made to focus on this problem.
I don't have any other script currently in my project. This is the CharacterController script that I used and it didn't work for me, I'll give you the link where I got it too
CharacterController: https://www.youtube.com/watch?v=FvvTDkJvBfA&t=1296s
RigidBody: https://www.youtube.com/watch?v=0oi8GzAm49k
I would be very grateful if you help me solve this error that I have, I have been searching for a solution or explanation for two days in forums and youtube videos

While this is not exactly an answer, this is the first step you could take to determine what the problem is, as per the comment above:
void Update ( )
{
var hor = Input.GetAxisRaw("Horizontal");
var ver = Input.GetAxisRaw("Vertical");
// If you're using a joystick that isn't quite calibrated, you might be getting a slight reading?
// Here we could check if the value is ALMOST 0:
// hor = Mathf.Approximately(hor, 0) ? 0 : hor;
if ( hor != 0f || ver != 0f )
{
Debug.Log ( $"Horizontal: {hor}. Vertical {ver}." );
var dir = (transform.forward * ver) + (transform.right * hor);
rigidbody.MovePosition ( transform.position + Time.deltaTime * speed * dir );
}
var accumulatedForce = rigidbody.GetAccumulatedForce ( );
if ( accumulatedForce != Vector3.zero )
{
Debug.Log ( $"accumulatedForce: {accumulatedForce}" );
}
}

Related

EnemyAI script not moving the Enemy

I am making my first foray into AI, specifically AI that will follow the player.
I am using the A* Path finding project scripts, but used the Brackeys tutorial for the code
https://www.youtube.com/watch?v=jvtFUfJ6CP8
Source in case needed.
Here's the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;
public class EnemyAI : MonoBehaviour
{
public Transform Target;
public float speed = 200f;
public float NextWayPointDistance = 3f;
Path path;
int currentWaypoint = 0;
bool ReachedEndOfpath = false;
Seeker seeker;
Rigidbody2D rb;
public Transform EnemyGraphics;
// Start is called before the first frame update
void Start()
{
seeker = GetComponent<Seeker>();
rb = GetComponent<Rigidbody2D>();
InvokeRepeating("UpdatePath", 0f, 1f);
}
void UpdatePath()
{
if (seeker.IsDone())
seeker.StartPath(rb.position, Target.position, OnPathComplete);
}
void OnPathComplete(Path p)
{
if (!p.error)
{
path = p;
currentWaypoint = 0;
}
}
// Update is called once per frame
void fixedUpdate()
{
if(path == null)
return;
if(currentWaypoint >= path.vectorPath.Count)
{
ReachedEndOfpath = true;
return;
}
else
{
ReachedEndOfpath = false;
}
Vector2 Direction = ((Vector2)path.vectorPath[currentWaypoint] - rb.position).normalized;
Vector2 Force = Direction * speed * Time.fixedDeltaTime;
rb.AddForce(Force);
float distance = Vector2.Distance(rb.position, path.vectorPath[currentWaypoint]);
if(distance < NextWayPointDistance)
{
currentWaypoint++;
}
if(rb.velocity.x >= 0.01f)
{
EnemyGraphics.localScale = new Vector3(-1f, 1f, 1f);
}else if(rb.velocity.x <= 0.01f)
{
EnemyGraphics.localScale = new Vector3(1f, 1f, 1f);
}
}
}
How I tried to fix the issue:
I thought it could've been a problem with the speed so I increased it to 10000000, and still nothing
Next I thought it was a problem with the Rigidbody2d so I check there, found the gravity scale was set at 0, so I increased it to 1. It made my enemy fall to the ground but still no movement.
I thought it could've been a problem with the mass and drag, so I set Linear drag and Angular drag to 0, and also set mass to 1. Still nothing.
I set the body type to kinematic, pressed run, nothing. Set the body type to static, pressed run, nothing. Set the body type to Dynamic, pressed run, still nothing.
I tried to make a new target for the enemy to follow, dragged the empty game object i nto the target, pressed run and still didn't move.
I am at a loss on how to fix this.
Please help?
Looks like maybe a typo? You have:
// Update is called once per frame
void fixedUpdate()
{
but the method is called FixedUpdate(), with a big F in front. You have fixedUpdate, which is NOT the same.

How to get 8 direction Movement with controller sticks | Topdown 3D Unity

Im working on an 3d rpg top down view in Unity. Something like the zelda links awakening remake.
What im trying to achieve ist that the player rotates to the direction you press and then just goes forwards and this in only 8 directions.
I already got this working with WASD and the dpad, there it obviously works because you cant press in between two buttons if you know what i mean.
But i need a way to clamp the joystick input to only the 8 directions. How can i achieve this ? I hope you understand what i mean. This is the code ive already written. Note that im using the new input system.
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private PlayerInputActions playerInput;
private Rigidbody rb;
[SerializeField]
private float playerSpeed;
private float angle;
private Quaternion targetRotation;
private Vector2 input;
private Transform cam;
void Awake()
{
playerInput = new PlayerInputActions();
rb = GetComponent<Rigidbody>();
}
void Start()
{
cam = Camera.main.transform;
}
void Update()
{
GetInput();
if (input.x == 0 && input.y == 0) return;
CalculateDirection();
Rotate();
Move();
}
void GetInput()
{
input.x = playerInput.Player.Move.ReadValue<Vector2>().x;
input.y = playerInput.Player.Move.ReadValue<Vector2>().y;
}
void CalculateDirection()
{
if (input.sqrMagnitude > 1.0f)
input = input.normalized;
angle = Mathf.Atan2(input.x, input.y);
angle = Mathf.Rad2Deg * angle;
angle += cam.eulerAngles.y;
}
void Rotate()
{
targetRotation = Quaternion.Euler(0, angle, 0);
transform.rotation = targetRotation;
}
void Move()
{
//transform.position += transform.forward * 5 * Time.deltaTime;
rb.velocity = transform.forward * 200 * Time.fixedDeltaTime;
}
void OnEnable()
{
playerInput.Enable();
}
void OnDisable()
{
playerInput.Disable();
}
} ```
You can do something like this to keep results in the same way that you're working at moment
private void CalculateDirection (InputAction.CallbackContext context)
{
var input = context.ReadValue<Vector2>();
var x = Mathf.Abs(input.x) <= .1f ? 0f : // Deadzone
input.x > 0 ? 1f : -1f; // Direction
var y = Mathf.Abs(input.y) <= .1f ? 0f :
input.y > 0 ? 1f : -1f;
var angle = Mathf.Atan2(x, y);
angle = Mathf.Rad2Deg * angle;
}
As you are working with gamepad stick and values here can be a range between -1..1 and when you get interactions from your keyboard buttons values are coming in 0, 1, or -1, similar to the Input.GetAxisRaw() in older input system, we don't need to normalize it.
This approach should work but I have a feeling that this will give some weird behaviors when controlling with the stick, I mean, maybe if you try to go up the player ends going to some side (UpRight or UpLeft) because the range for upper, down, right and left aren't really wide, I hope to be wrong but if I'm right you'll probably need to bite the bullet and manually decide a range/angle for each of the 8 sides. Try the above code and if you need help manually creating it just come back here and we try again.
N

How can I apply scripts in new camera which is child of a gameobject

Earlier I was facing problem regarding the unity camera problem it always stuck on 0,0,0.08 and also find a solution so I first create an empty gameobject and then drag the camera in that empty gameobject but after doing this the scripts which I applied to the gameobject is working fine but the script which I place in camera is not working at all
Camera Script
public float MovementAmplitude = 0.1f;
public float MovementFrequency = 2.25f;
void Update()
{
transform.position = new Vector3(
transform.position.x,
Mathf.Cos(transform.position.z * MovementFrequency) * MovementAmplitude,
transform.position.z
);
}
Player Script
public float speed = 4.5f;
public float JumpingForcec = 450f;
void Update()
{
transform.position += speed * Vector3.forward * Time.deltaTime;
if (Input.GetKeyDown("space"))
{
Debug.Log("SPace is pressed");
Debug.Log(GetComponent<Rigidbody>());
GetComponent<Rigidbody>().AddForce(Vector3.up * JumpingForcec);
}
}
First of all when dealing with a Rigidbody (or the Physics in general) you shouldn't set a position directly through the Transform component but rather use Rigidbody.position or in your case for a smooth movement even rather Rigidbody.MovePosition, both in FixedUpdate.
In general anything related to the Physics (so also everything using Rigidbody) should be done in FixedUpdate while the check for GetKeyDown has to be done in Update.
PlayerScript
public class PlayerScript : MonoBehaviour
{
public float speed = 4.5f;
public float JumpingForcec = 450f;
// If possible reference this in the Inspector already
[SerializeField] private Rigidbody rigidBody;
private bool jumpWasPressed;
private void Awake()
{
if (!rigidBody) rigidBody = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
rigidBody.MovePosition(transform.position + speed * Vector3.forward * Time.deltaTime);
if (!jumpWasPressed) return;
Debug.Log("SPace was pressed");
rigidBody.AddForce(Vector3.up * JumpingForcec);
jumpWasPressed = false;
}
private void Update()
{
// Note that currently you can multijump .. later you will want to add
// an additional check if you already jump again
if (Input.GetKeyDown(KeyCode.Space)) jumpWasPressed = true;
}
}
Make sure that Is Kinematic is disabled in the Rigidbody component! Otherwise AddForce is not processed.
If isKinematic is enabled, Forces, collisions or joints will not affect the rigidbody anymore.
The camera movement I would move to LateUpdate in order to make sure it is the last thing calculated after the other Update calls have finished. Especially after all user input has been processed (in your case maybe not that relevant since movement is processed in FixedUpdate but in general).
Second problem: Here you are not taking the changed Y position by jumping into account so rather add the "wobbling" effect to the player's transform.position.y and rather use the localPosition for the Camera:
public class CameraScript : MonoBehaviour
{
public float MovementAmplitude = 0.1f;
public float MovementFrequency = 2.25f;
// reference the player object here
public Transform playerTransform;
private float originalLocalPosY;
private void Start()
{
if(!playerTransform) playerTransform = transform.parent;
originalLocalPosY = transform.localPosition.y;
}
private void LateUpdate()
{
transform.localPosition = Vector3.up * (originalLocalPosY + Mathf.Cos(playerTransform.position.z * MovementFrequency) * MovementAmplitude);
}
}
Maybe you want to disable the wobbling effect during a jump later, though ;)
Try to put all the update stuff in the same method, it should work both (theorically, not tested) so you have to fix your code in order to get what you want:
void Update() {
// Camera update
transform.position = new Vector3(
transform.position.x,
Mathf.Cos(transform.position.z * MovementFrequency) * MovementAmplitude,
transform.position.z
);
// Player update
transform.position += speed * Vector3.forward * Time.deltaTime;
if (Input.GetKeyDown("space"))
{
Debug.Log("SPace is pressed");
Debug.Log(GetComponent<Rigidbody>());
GetComponent<Rigidbody>().AddForce(Vector3.up * JumpingForcec);
}
}
Hope this helps you, cheers!

How do I move the Rigidbody in FixedUpdate, but still have my character be affected by gravity?

So
Below you see what I initially used to control my characters movement.
_RigidBody.velocity = _ConstantWalkingSpeed * direction.normalized;
This works for walking around in 4 directions. However, if my character falls over an edge, he falls veeeeeery slowly. If I then in mid air disable the walking script, gravity picks up and goes at normal speed.
This leads me to believe that my movement script somehow affects the gravity effect.
As such I tried this solution:
_RigidBody.velocity = _ConstantWalkingSpeed * direction.normalized + new Vector3(0f, _RigidBody.velocity.y, 0f);
That didn't work either, so I tried this:
_RigidBody.velocity = _ConstantWalkingSpeed * direction.normalized + new Vector3(0f, _RigidBody.velocity.y, 0f) + Physics.gravity;
That did make the gravity work, but then the gravity became so strong that I can't move.
I tried only adding Physics.gravity and skipping the new vector part, but then the gravity is still too strong.
TL;DR
The movement script I use affects the players downward gravity, which it shouldn't. I want him to move around but still be affected by gravity. Ideas I have tried didn't work.
Please note that I'd prefer to keep the gravity at -9.81.
Hoping you guys have a suggestion that works :-)
Instead of setting or modifying the velocity, You can use RigidBody.movePositon:
Here is a quick example script I wrote up:
using UnityEngine;
public class simpleMoveRB : MonoBehaviour {
public Rigidbody myBody;
public float _constantWalkSpeed = 3.0f;
Vector3 moveDirection = Vector3.zero;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update() {
if (Input.GetKey(KeyCode.A))
{
moveDirection.x = -1.0f;
}
else if(Input.GetKey(KeyCode.D))
{
moveDirection.x = 1.0f;
}
else
{
moveDirection.x = 0.0f;
}
if(Input.GetKeyDown(KeyCode.Space))
{
myBody.AddForce(Vector3.up * 500.0f);
}
}
private void FixedUpdate()
{
myBody.MovePosition(transform.position + moveDirection * _constantWalkSpeed * Time.deltaTime);
}
}
You can handle movement using this script, and still have gravity work on your object.
Instead of setting the velocity, modify the velocity.
You're overwriting any velocity applied by the physics engine (e.g. gravity) with your input.
_RigidBody.velocity += _ConstantWalkingSpeed * direction.normalized;
You may also want to cap the velocity X and Z values to a maximum:
Vector3 vel = _RigidBody.velocity;
vel.x = Mathf.Min(vel.x, ConstantWalkingSpeed);
vel.z = Mathf.Min(vel.z, ConstantWalkingSpeed);
_RigidBody.velocity = vel;

unity animation.play() doesn't work

i have a simple script that should animate my player but its not working. i read forums for a while, some had issues about animation legacy option and i fixed it, but my character still doesn't animate, and there isn't any compiling errors. Here is my script:
using UnityEngine;
using System.Collections;
public class maincharacter : MonoBehaviour {
void Start () {
}
float xSpeed = 10f;
float zSpeed = 10f;
public float playerMovementSpeed = 10f;
void Update () {
float deltaX = Input.GetAxis ("Horizontal") * xSpeed;
float deltaZ = Input.GetAxis ("Vertical") * zSpeed;
Vector3 trans = new Vector3 (deltaX + deltaZ ,0f,deltaZ - deltaX);
transform.Translate (trans.normalized * Time.deltaTime * playerMovementSpeed, Space.World);
animation.Play ("mcrunsw");
/*if (deltaX != 0 || deltaZ != 0) {
animation.Play ("mcrunsw");
}*/
}
}
Here is my gameObject and animation:
Any help would be appreciated. Thanks in advance.
From the manual:
Play() will start animation with name animation, or play the default
animation. The animation will be played abruptly without any blending.
Since you call this every frame, I'd suppose it will just show the first frame of the animation and then be stopped by the next animation.Play in the next Update. Try this:
if (!animation.isPlaying) {
animation.Play();
}
In general, I would suggest using Mechanim for character animations.
Another viable option along with the solution above is CrossFadeQueued.
You just simply use the function below and it'll seamlessly CrossFade.
usage is PlayAnimation("mcrunsw");
function PlayAnimation(AnimName : String) {
if (!animation.IsPlaying(AnimName))
animation.CrossFadeQueued(AnimName, 0.3, QueueMode.PlayNow);
}

Categories