How can I make my jump and land animations play reliably? - c#

I can't make my jump and land animations play reliably Currently the jump animation doesn't play and the land animation seems to play randomly.
I've been working with unity 3d for several months but I am new to using animations. I may just be missing some basic information.
At one point the jump animation would play, but only after the player was in the air. How do I make animations play at the right time reliably?
This is my player movement script where I'm currently calling the jump and land animations from.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMvmt : MonoBehaviour
{
public Rigidbody player;
public float sideForce = 5;
public float jumpForce = 5;
public float fallingForce = 10;
public SphereCollider col;
public LayerMask groundLayers;
public Animator jump;
public Animator land;
private void Start()
{
jump = GetComponent<Animator>();
land = GetComponent<Animator>();
}
private void Update()
{
if ( Input.GetKey("a"))
{
player.AddForce(-sideForce, 0, 0);
}
if ( Input.GetKey("d"))
{
player.AddForce(sideForce, 0, 0);
}
if (IsGrounded() && Input.GetKey("w"))
{
jump.SetBool("playJump",true);
Invoke("StopJumpAnimation", .4f);
player.AddForce(0, jumpForce, 0);
}
OncollisionEnter();
if (IsGrounded() == false)
{
player.AddForce(0, -fallingForce, 0);
}
}
private bool IsGrounded()
{
return Physics.CheckCapsule(col.bounds.center,
new Vector3(col.bounds.center.x,
col.bounds.min.y, col.bounds.center.z), col.radius * .9f, groundLayers);
}
void StopJumpAnimation()
{
jump.SetBool("playJump", false);
}
void StopLandAnimation()
{
land.SetBool("playLand", false);
}
void OncollisionEnter()
{
land.SetBool("playLand", true);
Invoke("StopLandAnimation", .3f);
}
}
I can show you pictures of the animator if that helps. I might just need a basic explanation of how to use the animator since I'm new to animation.

Related

Why can I not collect coins and I get an error message

I'm new to unity and C# as well but I do have a small understanding of it because I've learnt python. At the moment I've run into an error, I'm trying to make a coin collection system and also the players movement in one script simply because it seems neater that way and easier to play audio.
The error comes up on this line, [SerializeField] private Transform groundcheck = null; (it's used so the player can jump over and over). I have a theory that maybe I just need to change the collision value, but other then no clue what I need to do to change this error.
Full Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField] private Transform groundcheck = null;
private bool jumpkeywaspressed;
private float horizontalInput;
private Rigidbody rigibodycomponent;
public AudioSource coincollect;
// Start is called before the first frame update
void Start()
{
rigibodycomponent = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
jumpkeywaspressed = true;
horizontalInput = Input.GetAxis("Horizontal");
}
private void FixedUpdate()
{
rigibodycomponent.velocity = new Vector3(horizontalInput * 3, rigibodycomponent.velocity.y,0);
if (Physics.OverlapSphere(groundcheck.position, 0.1f).Length == 1)
{
return;
}
if (jumpkeywaspressed)
{
rigibodycomponent.AddForce(Vector3.up * 5, ForceMode.VelocityChange);
jumpkeywaspressed = false;
}
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.layer == 6)
{
coincollect.Play();
ScoreManager.sManger.IncreaseScore(1);
Destroy(other.gameObject);
}
}
}
I also have another script which is used to increase the score but I don't think it effects my error.

System Inputs - How to make my game object jump?

I'm making a simple platformer with a rolling ball that rolls around and collects coins to win each level. I'm using Unity's System input from Unity's package manager to help me with controls and key binding and have successfully gotten my ball to roll around with ease and collect coins with a nice UI setup. However, I would like to implement harder levels where the ball jumps. I can not figure out how to make the ball jump. I know there are others ways to go about this but I just can't figure out how to make it work in the system inputs.
(I know an if statement is needed to test if the ball is grounded however again I'm new and still learning)
Gameplay | OnJump in player input is for jumping | KeyBindings
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;
public class PlayerController: MonoBehaviour
{
public float speed = 0;
public bool isGrounded;
public float jumpForce;
public TextMeshProUGUI countText;
public GameObject winTextObject;
private Rigidbody rb;
private int count;
private float movementX;
private float movementY;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
SetCountText();
winTextObject.SetActive(false);
}
private void OnMove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get<Vector2>();
movementX = movementVector.x;
movementY = movementVector.y;
}
private void onJump(InputValue value)
{
}
void SetCountText()
{
countText.text = "Count: " + count.ToString();
if(count >= 12)
{
winTextObject.SetActive(true);
}
}
private void FixedUpdate()
{
Vector3 movement = new Vector3(movementX, 0.0f, movementY);
rb.AddForce(movement * speed);
}
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.CompareTag("PickUp"))
{
other.gameObject.SetActive(false);
count = count + 1;
SetCountText();
}
}
}
Make sure you create a new tag called Ground and put it on everything you want your player to be able to jump on (the ground).
public float jumpHeight = 5f;
public bool isGrounded;
void Update()
{
if (isGrounded)//Checks if is on ground
{
if (Input.GetButtonDown("Jump"))//If the space is pressed
{
rb.AddForce(Vector3.up * jumpHeight)
}
}
}
void OnCollisionEnter(Collision other)//If touch other object
{
if (other.gameObject.tag == "Ground")//If other object has Ground tag
{
isGrounded = true;
}
}
void OnCollisionExit(Collision other)
{
if (other.gameObject.tag == "Ground")
{
isGrounded = false;
}
}
You can also do if (Input.GetButtonDown("Jump")) as
if (Input.GetKeyDown("space"))
or
if (Input.GetKeyDown(KeyCode.Space))

Touch movement for phone

I started making a 2D game in Unity and I have a problem with my player. I add 2 buttons for left and right and jump just tapping the display . When I start the game just the buttons left and right works and the jump don't . I added from another script something for jump and now when I start the game the player goes automatically at right and don't respect the buttons action. (but jumping works) this is the 2 codes that I joined them :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
public float moveSpeed = 300;
public GameObject character;
private Rigidbody2D characterBody;
private float ScreenWidth;
void Start()
{
ScreenWidth = Screen.width;
characterBody = character.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
int i = 0;
while (i < Input.touchCount)
{
if (Input.GetTouch(i).position.x > ScreenWidth / 2)
{
RunCharacter(1.0f);
}
if (Input.GetTouch(i).position.x < ScreenWidth / 2)
{
RunCharacter(-1.0f);
}
++i;
}
}
void FixedUpdate()
{
#if UNITY_EDITOR
RunCharacter(Input.GetAxis("Horizontal"));
}
private void RunCharacter(float horizontalInput)
{
characterBody.AddForce(new Vector2(horizontalInput * moveSpeed * Time.deltaTime, 0));
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move2d : MonoBehaviour
{
public float playerSpeed; //allows us to be able to change speed in Unity
public Vector2 jumpHeight;
public bool isDead = false;
private Rigidbody2D rb2d;
private Score gm;
// Use this for initialization
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
gm = GameObject.FindGameObjectWithTag("gameMaster").GetComponent<Score>();
}
// Update is called once per frame
void Update()
{
if (isDead) { return; }
transform.Translate(playerSpeed * Time.deltaTime, 0f, 0f); //makes player run
if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space)) //makes player jump
{
GetComponent<Rigidbody2D>().AddForce(jumpHeight, ForceMode2D.Impulse);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("ground")) // this will return true if the collision gameobject has ground tag on it.
{
isDead = true;
rb2d.velocity = Vector2.zero;
GameController.Instance.Die();
}
}
void OnTriggerEnter2D(Collider2D col)
{
if( col.CompareTag("coin"))
{
Destroy(col.gameObject);
gm.score += 1;
}
}
}
If you know a better script please help
Try adding #endif for the #if UNITY_EDITOR

How would I implement navmesh pathfinding into this AI following code. C# Unity

I have this code that makes the enemy follow my player(And attack etc) but im not sure how to add navmesh into this so it can navigate obstacles. Currently, it goes forward and gets stuck on walls and obstacles.
I have never used navmesh before.
How would I implement navmesh pathfinding into this code.
Thank you.
using UnityEngine;
using System.Collections;
public class wheatleyfollow : MonoBehaviour {
public GameObject ThePlayer;
public float TargetDistance;
public float AllowedRange = 500;
public GameObject TheEnemy;
public float EnemySpeed;
public int AttackTrigger;
public RaycastHit Shot;
void Update() {
transform.LookAt (ThePlayer.transform);
if (Physics.Raycast (transform.position, transform.TransformDirection (Vector3.forward), out Shot)) {
TargetDistance = Shot.distance;
if (TargetDistance < AllowedRange) {
EnemySpeed = 0.05f;
if (AttackTrigger == 0) {
transform.position = Vector3.MoveTowards (transform.position, ThePlayer.transform.position, EnemySpeed);
}
} else {
EnemySpeed = 0;
}
}
if (AttackTrigger == 1) {
EnemySpeed = 0;
TheEnemy.GetComponent<Animation> ().Play ("wheatleyattack");
}
}
void OnTriggerEnter() {
AttackTrigger = 1;
}
void OnTriggerExit() {
AttackTrigger = 0;
}
}
To start off, we will require a NavMeshAgent on the object that will hold this script and we will then save a reference to the agent. We will also need a NavMeshPath to store our path (This isn't an attachable component, we will create it within the code).
All we need to do is update the path using CalculatePath and SetPath. You may need to fine tune the code some, but this is the very basics. You can use CalculatePath to generate a path then decide if you want to execute that path by using SetPath.
Note: We could use SetDestination, but if you have many AI units it can become slow if you need instant paths, which is why I normally use CalculatePath and SetPath.
Now all that is left is to make your navmesh Window -> Navigation. In there you can finetune your agents and areas. One required step is to bake your mesh in the Bake tab.
Unity supports navmeshes on components for prefabs and other things, however, these components are not yet built into Unity, as you will need to download them into your project.
As you can see all of your speed and movement has been removed since it is now controlled by your NavMeshAgent.
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(NavMeshAgent))]
public class wheatleyfollow : MonoBehaviour {
public GameObject ThePlayer;
public float TargetDistance;
public float AllowedRange = 500;
public GameObject TheEnemy;
public int AttackTrigger;
public RaycastHit Shot;
private NavMeshAgent agent;
private NavMeshPath path;
void Start() {
path = new NavMeshPath();
agent = GetComponent<NavMeshAgent>();
}
void Update() {
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out Shot)) {
TargetDistance = Shot.distance;
if (TargetDistance < AllowedRange && AttackTrigger == 0) {
agent.CalculatePath(ThePlayer.transform.position, path);
agent.SetPath(path);
}
}
if (AttackTrigger == 1) {
TheEnemy.GetComponent<Animation>().Play("wheatleyattack");
}
}
void OnTriggerEnter() {
AttackTrigger = 1;
}
void OnTriggerExit() {
AttackTrigger = 0;
}
}
Side Note: You should remove any using's that you are not using, as this can bloat your final build.

unity3D, enemy following issue

I'm trying to make enemies follow my player when the player enters the radius area of an enemy, but make the enemy stop following when my bullet hits object or enters radiusArea.
See my gif for more detail:
Gif
script:
using UnityEngine;
using System.Collections;
public class FlyEnemyMove : MonoBehaviour
{
public float moveSpeed;
public float playerRange;
public LayerMask playerLayer;
public bool playerInRange;
PlayerController thePlayer;
// Use this for initialization
void Start()
{
thePlayer = FindObjectOfType<PlayerController>();
}
// Update is called once per frame
void Update()
{
flip();
playerInRange = Physics2D.OverlapCircle(transform.position, playerRange, playerLayer);
if (playerInRange)
{
transform.position = Vector3.MoveTowards(transform.position, thePlayer.transform.position, moveSpeed * Time.deltaTime);
//Debug.Log(transform.position.y);
}
//Debug.Log(playerInRange);
}
void OnDrawGizmosSelected()
{
Gizmos.DrawWireSphere(transform.position, playerRange);
}
void flip()
{
if (thePlayer.transform.position.x < transform.position.x)
{
transform.localScale = new Vector3(0.2377247f, 0.2377247f, 0.2377247f);
}
else
{
transform.localScale = new Vector3(-0.2377247f, 0.2377247f, 0.2377247f);
}
}
}
I hope someone can help me :(
Physics2D.OverlapCircle detects only the collider with the lowest z value (if multiple are in range). So you either need to change the z values so the player has the lowest or you need to work with Physics2D.OverlapCircleAll and check the list to find the player. Or you could change your layers so only the player itself is on that specific layer you feed into the overlap test.

Categories