Unity blend tree in animator not working/jittering - c#

I am using unity version: 2021.3.6f1
I have setup indevidual animations for the player (four-way idle and walk) and I am using two blend trees which the script accesses and changes the variables moveX, moveY and is_idle. I am using the new Unity input system:
Screenshot of new Unity input system.
and cinemachine (cinemachine isn't causing problems though).
When I run the script, it has a weird jittering effect as if the animator keeps reseting the animation playback. Below is a video.
Link to video
Screenshot of the animator:
Screenshot of the animator
Here is the code in the player controller:
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 1f;
public ContactFilter2D movementFilter;
public float collissionOffset = 0.05f;
Vector2 inputaxis;
Vector2 movementInput;
Vector2 prevMovementInput;
Rigidbody2D rb;
Animator animator;
List<RaycastHit2D> castCollissions = new List<RaycastHit2D>();
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
private void FixedUpdate() {
if(movementInput != Vector2.zero){
bool success = TryMove(movementInput);
if(movementInput != prevMovementInput) {
animator.SetFloat("moveX", movementInput.x);
animator.SetFloat("moveY", movementInput.y);
prevMovementInput = movementInput;
}
if(!success){
success = TryMove(new Vector2(movementInput.x, 0));
if(!success){
success = TryMove(new Vector2(0, movementInput.y));
}
}
animator.SetBool("is_idle",false);
} else {
//animator.SetBool("is_idle", true);
}
}
private bool TryMove(Vector2 direction){
int count = rb.Cast(direction,
movementFilter,
castCollissions,
moveSpeed * Time.fixedDeltaTime + collissionOffset);
if(count == 0){
rb.MovePosition(rb.position + direction * moveSpeed * Time.fixedDeltaTime);
return true;
} else {
return false;
}
}
void UpdateAnimation_DONT_USE(){
// this is my origional function that would be called when I didn't have a blend tre
//animation direction
if(movementInput.x == 0.00d){
if(movementInput.y ==1.00d){
//up
animator.SetInteger("direction",1);
}
}else if(movementInput.x == 1.00d) {
if(movementInput.y == 0.00d){
//right
animator.SetInteger("direction",2);
}
}else if(movementInput.x == 0.00d) {
if(movementInput.y == -1.00d){
//down
animator.SetInteger("direction",3);
}
}else if(movementInput.x == -1.00d){
if(movementInput.y == 0.00d){
//left
animator.SetInteger("direction",4);
}
}
}
void OnMove(InputValue movementValue) {
movementInput = movementValue.Get<Vector2>();
}
}
The youtube video I used
First, I had lots of transition arrows going from the Any State block to all of the animation phases. When I tried it, the same result occured. I then watched a different youtube video which showed how to use a blend tree
I still have no idea what the problem is after trying a lot of different things.
If anyone can help, it would be much appreciated.
:)

I have found a solution meaning that I have to remake the game.
Even though I still don't know what the problem is, I used the default input system in a new prodject and it works fine.
Thanks to everyone who tried to help me! :)

Related

Unity2D Jump doesn't work for unknown reasons

I am going back into game devloppment after a few months and, while I was making a respawn trigger (that doesn't work), my jump stopped working for no reasons. I didn't modified the code (I think). I followed a tutorial for the code. Please not that I am using the unity new input system and that my game is a 2D GAME Also, there is no errors shown in the logs, the problem is that when I press my jump key, it does nothing. I tried putting Debug.Log("Should Jump"); in the jump code to see if the Rigidbody2D was the problem but it still didn't worked (nothing showed up in the logs). I also verified that my floor was in the Ground layer and it was. I don't see the problem.
My code is the following:
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] float speed;
[SerializeField] Transform groundCheck;
[SerializeField] LayerMask groundLayer;
bool facingRight = true;
PlayerInput playerInput;
bool isGrounded;
float groundTimer = 1f;
float airTimer;
void Start()
{
playerInput = GetComponent<PlayerInput>();
}
void Update()
{
Movement();
isGround();
}
void isGround()
{
if (Physics2D.OverlapCircle(groundCheck.position, 0.05f, groundLayer) && airTimer <- 0)
{
groundTimer = 0.15f;
isGrounded = true;
}
if (airTimer > 0)
{
airTimer -= Time.deltaTime;
}
else
{
if (groundTimer < 0)
isGrounded = false;
else
groundTimer -= Time.deltaTime;
}
}
void Movement()
{
transform.Translate(Mathf.Abs(playerInput.actions["Horizontal"].ReadValue<float>()) * speed * Time.deltaTime, 0, 0);
//if (playerInput.actions["Jump"].triggered)
if (playerInput.actions["Jump"].triggered && isGrounded && airTimer <- 0)
{
GetComponent<Rigidbody2D>().velocity = Vector2.zero;
GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 10), ForceMode2D.Impulse);
Debug.Log("Should Jump");
isGrounded = false;
airTimer = 0.06f;
}
//Just flipping
}
//More flipping
}
Help...
(It's late for me so, if you ask a question, I will probably not anwser (22:52 EST 19 June 2022))

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.

I'm try to make game using unity and my Jump functionality not working

I'm trying to make simple 2D game following tutorials when I did same thing as tutorial my jump functionality not working and left and right move functionality working please help me below I attached my source code and relevant screen shot
my player class
public class Player : MonoBehaviour
{
private Rigidbody2D _rigid;
//variable for jump
[SerializeField]
private float _jumpForce = 5.0f;
[SerializeField]
private LayerMask _grondLayer;
private bool _resetJump = false;
// Start is called before the first frame update
void Start()
{
_rigid = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
Movement();
}
void Movement()
{
float move = Input.GetAxisRaw("Horizontal");
_rigid.velocity = new Vector2(move,_rigid.velocity.y);
if(Input.GetKeyDown(KeyCode.Space) && IsGrounded()==true)
{
Debug.Log("jump");
_rigid.velocity = new Vector2(_rigid.velocity.x,_jumpForce);
StartCoroutine(ResetJumpNeededRoutine());
}
}
bool IsGrounded()
{
RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, Vector2.down, 0.6f, _grondLayer);
if(hitInfo.collider != null)
{
if(_resetJump==false){return true;}
}
return false;
}
IEnumerator ResetJumpNeededRoutine()
{
_resetJump = true;
yield return new WaitForSeconds(0.1f);
_resetJump = false;
}
}
Correct way to implement the jump mechanism on 2d character.
_rigid.AddForce(new Vector2(0, _jumpForce), ForceMode2D.Impulse);
The problem is probably the LayerMask you selected Ground layer to be ignored therefore IsGrounded function will return false.
What you wanna do is select the layers you'd like your Raycast to ignore (All except Ground I assume) in the unity editor then give it another go.

2d Platformer game stone changing size

I am trying to make a platformer game. In the platformer game has a moving platform that makes everything it touches its transform's child while it touches it. Interestingly, whenever a stone(A movable object with a rigidbody and a polygon collider) touches the moving platform, the stone's scale goes haywire. Even though the scale reads the same on the transform component, it appears to be larger or smaller than it really is when touching it. When it stops touching the platform, the stone appears normal. Can anyone help me. Thank you.
This is the moving platform script that moves the platform around.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveTwoTransforms : MonoBehaviour
{
public Transform pointA;
public Transform pointB;
public bool HasReachedA;
public bool HasReacedB;
// Start is called before the first frame update
void Start()
{
transform.position = pointA.position;
HasReacedB = true;
HasReachedA = false;
StartCoroutine(GlideAround());
}
// Update is called once per frame
void Update()
{
}
public IEnumerator GlideAround()
{
while (true)
{
while (HasReachedA == false)
{
yield return new WaitForEndOfFrame();
transform.position = Vector2.Lerp(transform.position, pointA.position, 0.01f);
if ((Mathf.Abs(Vector2.Distance(pointA.position, transform.position)) < 0.01f))
{
HasReacedB = false;
HasReachedA = true;
}
}
while (HasReacedB == false)
{
yield return new WaitForEndOfFrame();
transform.position = Vector2.Lerp(transform.position, pointB.position, 0.01f);
if ((Mathf.Abs(Vector2.Distance(pointB.position, transform.position)) < 0.01f))
{
HasReacedB = true;
HasReachedA = false;
}
}
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if((collision.gameObject.tag == "Stone"|| collision.gameObject.tag == "Player") && (collision.transform.position.y - collision.transform.lossyScale.y / 2 >= transform.position.y))
{
collision.transform.parent = transform;
}
}
private void OnCollisionExit2D(Collision2D collision)
{
collision.transform.parent = null;
}
}
This is the stone script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RememberPositions : MonoBehaviour
{
public Vector3 StartingPosition;
public Vector3 StartingRotation;
public Vector3 StartingScale;
float StartRotation;
// Start is called before the first frame update
void Start()
{
StartingPosition = new Vector3(transform.position.x, transform.position.y, 0);
StartingRotation = new Vector3(0, 0, transform.position.z);
StartingScale = new Vector3(transform.localScale.x, transform.localScale.y, transform.localScale.z);
}
// Update is called once per frame
void Update()
{
transform.localScale = StartingScale;
}
}
There are no errors whatsoever and the rigidbody seems to be changing to the shape of the stone. Can anyone please specify the correct code I should use? Thank you.
If your moving platform is scaled, your stone will get scaled too. There are workarounds shown here to avoid this issue. One of them is adding a child GameObject to the platform, and moving the collision handling from the platform to that child.

I am trying to make an FPS soccer game using Unity, but my script isn't working

So, I am trying to create a soccer game from scratch... all I have done until now, is setting up the ball. This is how I want it to work: When the player collides with the ball, the ball jumps forward a bit. If you start running the ball will be pushed further away.
Now, here is my script for the ball (I am using the standard FPSController as character):
using UnityEngine;
using System.Collections;
public class BallController : MonoBehaviour {
private Rigidbody rb;
public GameObject character;
public float moveSpeed = 1000;
public float shootSpeed = 2000;
bool isTurnedUp = false;
bool isTurnedDown = false;
bool done = false;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
//Debug.Log(isTurnedUp + ", " + isTurnedDown);
switch (character.GetComponent<UnityStandardAssets.Characters.FirstPerson.FirstPersonController>().m_IsWalking)
{
case true:
if (isTurnedUp == false)
{
moveSpeed = moveSpeed / 1.4f;
isTurnedUp = true;
isTurnedDown = false;
}
break;
case false:
if (isTurnedDown == false)
{
moveSpeed = moveSpeed * 1.4f;
isTurnedDown = true;
isTurnedUp = false;
}
break;
}
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (Vector3.Distance(gameObject.transform.position, character.transform.position) <= 5)
{
float distance = Vector3.Distance(gameObject.transform.position, character.transform.position);
}
}
}
void OnCollisionEnter(Collision collision) {
FixedUpdate();
if (done == false) {
rb.AddForce(Vector3.forward * moveSpeed, ForceMode.Impulse);
done = true;
}
else {
done = false;
}
}
//other
void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, 2);
}
}
My problem is that the ball doesn't behave how I want it... it feels like it's about luck if the ball will jump forward when I touch it. Can someone tell me what I did wrong?
Inside of OnCollisionEnter you need to ensure the ball can only be kicked by the player. You can check whether or not the player has collided with the ball by checking the name or tag of the collision. The following example uses the name and assumes your player GameObject is named "Player".
Remove the done flag since this will only allow the player to kick the ball every other time they collide, and remove the FixedUpdate() call since FixedUpdate() is already called automatically every physics calculation.
Finally, if you want to kick the ball away from the player, then you need to calculate the direction away from the collision point instead of using Vector3.forward as seen below.
void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.name == "Player")
{
Vector3 direction = (collision.transform.position - transform.position).normalized;
rb.AddForce(-direction * moveSpeed, ForceMode.Impulse);
}
}

Categories