Why sometimes the player is making a circle movement around the target? - c#

The main goal of the script in this case is when the player is getting too close to the fire to slowly stop walking automatic wait some seconds then automatic rotate and start walking again and then stop again slowly.
The script is working when the player is entering the collider area this is the target variable position so the player is rotating back to where he was entered from.
The idea is to make something nice to prevent from the player to get into the fire. but i'm facing two problems.
The first problem is that in the script i'm using a box collider as the area to prevent from the player to get closer to the fire and it's hard to dynamic change the collider area shape to cover all sides.
This is a screenshot of the collider area :
I marked to possible places if the player is coming from closer to the fire when he enter/exit the collider area he is already inside the fire and it's hard to change the collider size and scale to cover this places too.
I wonder if using distance check instead of the box collider will be easier ? and if it is how to change the script to use distance check instead the box collider trigger enter and exit events ?
The second problem is that sometimes when the player got close to the fire and then rotating back outside the collider area when he exit at that point(position) the player is making a walking circle around the target position and then continue outside. not sure why the player is making sometimes a moving around the target point ?
The script is attached to the player :
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;
public class SpreadedFireDistanceCheck : MonoBehaviour
{
public Vector3 target;
public float rotationSpeed;
public GameObject descriptionTextImage;
public TextMeshProUGUI text;
public Transform player;
private Animator anim;
private ThirdPersonUserControl thirdPersonUserControl;
private bool startRotBack = false;
private bool rot = false;
private bool doOnce = true;
private bool getTargetPos = false;
float angle = 10;
// Start is called before the first frame update
void Start()
{
anim = player.GetComponent<Animator>();
thirdPersonUserControl = player.GetComponent<ThirdPersonUserControl>();
}
// Update is called once per frame
void Update()
{
if (startRotBack)
{
if (doOnce)
{
anim.SetTrigger("Idle Exit");
StartCoroutine(WaitTime());
doOnce = false;
}
if (rot)
{
anim.SetBool("Walk", true);
if (Vector3.Angle(player.transform.forward, target - player.transform.position) > angle)
{
Vector3 dir = target - player.transform.position;
Quaternion lookRotation = Quaternion.LookRotation(dir);
Vector3 rotation = Quaternion.Lerp(player.transform.rotation, lookRotation, Time.deltaTime * rotationSpeed).eulerAngles;
player.transform.rotation = Quaternion.Euler(0f, rotation.y, 0f);
}
}
}
}
private void OnTriggerExit(Collider other)
{
if (other.name == "kid_from_space")
{
if (rot)
{
rot = false;
anim.SetBool("Walk", false);
anim.SetTrigger("Idle Enter");
thirdPersonUserControl.enabled = true;
getTargetPos = false;
}
}
}
private void OnTriggerEnter(Collider other)
{
if (other.name == "kid_from_space")
{
if (getTargetPos == false)
{
target = player.transform.position;
getTargetPos = true;
}
descriptionTextImage.SetActive(true);
text.text = "This flames are so hot, i better stay away.";
thirdPersonUserControl.enabled = false;
doOnce = true;
startRotBack = true;
}
}
private IEnumerator WaitTime()
{
yield return new WaitForSeconds(5f);
text.text = "";
descriptionTextImage.SetActive(false);
rot = true;
}
}
In general the script is working but this two problem i mentioned above is hard to solve.
The player have this components :
Animator , Rigidbody , Capsule Collider , Third Person User Control (Script) , Third Person Character (Script)

Related

My player is getting stuck inside the wall in the 2D platforming game I am making in unity

I am making a 2D platforming game in unity. For some reason, the player is getting stuck in the wall. I have used a Tilemap for the wall, then used tilemap Collider 2D with composite collider. The same thing works fine with the ground.
When I go left facing the wall, it behaves as expected:
When I release the left arrow button, it also shows the expected result:
But when I click right arrow next, the player gets stuck inside the wall:
and cannot get out:
Here is my player movement code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerScript : MonoBehaviour
{
// Start is called before the first frame update
[SerializeField] private float movement_speed = 2;
[SerializeField] private float jump_power = 5;
[SerializeField] private LayerMask groundLayer;
[SerializeField] private LayerMask wallLayer;
private Rigidbody2D rb_player;
private BoxCollider2D boxCollider;
private Animator anim;
private void Start()
{
}
private void Awake()
{
rb_player = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
boxCollider = GetComponent<BoxCollider2D>();
groundLayer = LayerMask.GetMask("ground");
wallLayer = LayerMask.GetMask("wall");
}
// Update is called once per frame
private void Update()
{
float x = Input.GetAxis("Horizontal");
rb_player.velocity = new Vector2(x * movement_speed, rb_player.velocity.y);
//flip the player
if(x > 0.01f)
{
transform.localScale = new Vector3(1, 1, 1);
}
else if(x < -0.01f)
{
transform.localScale = new Vector3(-1, 1, 1);
}
if(Input.GetKeyDown(KeyCode.Space) && isGrounded())
{
jump();
}
anim.SetBool("run", x != 0);
anim.SetBool("jump", !isGrounded());
print("wall: "+isTouchingWall());
print("ground: "+isGrounded());
}
private void jump()
{
rb_player.velocity = new Vector2(rb_player.velocity.x, jump_power);
anim.SetTrigger("jump_trigger");
}
private void OnCollisionEnter2D(Collision2D collision)
{
// if(collision.gameObject.tag == "ground")
// {
// grounded = true;
// }
}
private bool isGrounded()
{
RaycastHit2D raycastHit = Physics2D.BoxCast(boxCollider.bounds.center, boxCollider.bounds.size, 0, Vector2.down, .2f, groundLayer);
return raycastHit.collider != null;
}
private bool isTouchingWall()
{
RaycastHit2D raycastHit = Physics2D.BoxCast(boxCollider.bounds.center, boxCollider.bounds.size, 0, new Vector2(transform.localScale.x,0), .1f, wallLayer);
return raycastHit.collider != null;
}
}
It would be nice if anyone can help me as I am a complete beginner in game development with unity.
The problem
Your pivot point of your player (where your player script is attached) isn't centered like your collider. Because of this, your box collider is being flipped like a page from a book and it lands inside the wall.
To fix it
Make sure that your player pivot point is the same as the center of your BoxCollider2D. This way, your collider won't "teleport" from right to left and bypass walls.
Other tips
I see some beginner's mistakes in your code, so even if you manage to fix your issue, I highly recommend to follow the next tips:
All physic based code (jump, movement, etc.) should go inside FixedUpdate() method and use Time.deltaTime or Time.fixedDeltaTime to keep the same speed (for movement and jump) among computers.
Use the proper naming conventions, your variables should be camel case, no underscores. Methods (and Classes) should always start with a capital letter in C# (PascalCase).
Hopefully this will help you.

How to have a rigidbody object "ride" a falling platform, while still being able to move horizontally

I'm making a 2D game in Unity, which has falling platforms that the player can "ride" down. I want the player to still be able to move left or right (ie horizontally) while standing on a falling platform. Without additional code, just using the Rigidbody physics, the player does fall along with the platform, but the falling is choppy, and the game doesn't always see the player is standing on the platform (important because the player can only jump while standing on something).
I've tried setting the player object's transform.translate, which prevents the player from moving left or right as long as it is touching the platform. I've also tried setting the player object's transform.parent to the platform's transform, but that "glues" the player in place to the platform, preventing even jumping. I've also tried searching for a solution/example, and there are plenty of examples for riding a left-right moving platform, but I haven't been able to get those examples to work for a falling platform.
Here is the script controlling the players left-right movement and jumping. This is attached to the player object:
public class Player : MonoBehaviour
{
public float jumpForce = 5;
public float horizontalSpeed = 0.1F;
public LayerMask whatIsGround;
private Rigidbody2D rb2d;
private Collider2D myCollider;
private bool grounded;
private float lastHorizontalInput;
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
myCollider = GetComponent<Collider2D>();
}
void Update()
{
// If the player is trying to jump, only do so if the player is on a platform
grounded = Physics2D.IsTouchingLayers(myCollider, whatIsGround);
if (Input.GetKeyDown(KeyCode.Space) && grounded)
{
rb2d.velocity = new Vector2(rb2d.velocity.x, jumpForce);
}
MoveHorizonltally();
}
private void MoveHorizonltally()
{
float horizontalVelocity;
float horizontalInput = Input.GetAxis("Horizontal");
horizontalVelocity = GetHorizontalVelocity(horizontalInput);
if (horizontalVelocity != 0)
{
rb2d.position = new Vector2(rb2d.position.x + horizontalVelocity, rb2d.position.y);
}
}
private float GetHorizontalVelocity(float horizontalInput)
{
// Default to no horizontal motion
float result = 0;
bool leftPressed = Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow);
bool rightPressed = Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow);
// Only a left key is being pressed; the player is going left
if (leftPressed && !rightPressed)
{
result = -1 * horizontalSpeed;
}
// Only a right key is being pressed; the player is going right
else if (rightPressed && !leftPressed)
{
result = horizontalSpeed;
}
// Both keys are being pressed
else if (leftPressed && rightPressed)
{
// The most recent key press gets priority; ignore the oldest key press
if (lastHorizontalInput < 0)
{
// Oldest key pressed is a left direction, so go right
result = horizontalSpeed;
}
else
{
// Oldest key pressed is a right direction, so go left
result = -1 * horizontalSpeed;
}
}
lastHorizontalInput = horizontalInput;
return result;
}
}
Here is the script responsible for making the platform fall. This is attached to the platform object:
public class PlatformFalling : MonoBehaviour
{
public float fallSpeed;
private GameObject player;
public void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
}
// Update is called once per frame
void Update()
{
bool playerIsOnPlatform = player.GetComponent<Collider2D>().IsTouching(GetComponent<Collider2D>()); ;
Vector2 fallDistance = Vector2.down * fallSpeed;
transform.Translate(fallDistance);
if (playerIsOnPlatform)
{
player.transform.Translate(fallDistance);
}
}
}

How do I change a GameObject's rotation equal to my player camera's rotation?

Im working on a first person shooter. I have an aim function, which puts the pistol right in front of the camera, to make it look like your holding it in front of you. Im trying to make it so the pistol will also rotate with the camera on the Z axis, so that way the pistol wont stay still, because that looks odd and gets in the way. To do this, I tried this:
GPR.gun.transform.rotation = Quaternion.Euler(0, 0, plrCam.transform.rotation.z);, however this ends up rotating the gun very slightly around the z axis, and mainly rotating it around the y axis whenever I move my camera. I am a beginner programmer in Unity so please try to make answers more digestible to beginners so I can understand it. Here is my full script:
using System.Collections.Generic;
using UnityEngine;
public class PistolFire : MonoBehaviour
{
//Gun Properties
public float range = 50f;
public float damage = 10f;
//Sensitivity decrease for looking down the sights
public float downSights = 5f;
//Other vars
private playerGunControls playerGun;
private GameObject plrCam;
private Camera fpsCam;
private ParticleSystem muzzleFlash;
private GameObject impactEffect;
private bool aimed = false;
private GameObject aimPos;
private GunPickupRaycast GPR;
private GameObject handPos;
private GameObject Player;
// Start is called before the first frame update
void Start()
{
//Getting objects because gun is instantiated, so this is necessary
plrCam = GameObject.Find("Player Camera");
playerGun = plrCam.GetComponent<playerGunControls>();
fpsCam = plrCam.GetComponent<Camera>();
muzzleFlash = GetComponentInChildren<ParticleSystem>();
impactEffect = GameObject.Find("Impact Effect");
aimPos = GameObject.Find("aimPos");
GPR = plrCam.GetComponent<GunPickupRaycast>();
handPos = GameObject.Find("Hand Pos");
Player = GameObject.Find("Player");
}
// Update is called once per frame
void Update()
{
//Check for shoot button down
if (Input.GetButtonDown("Fire1"))
{
if (playerGun.holding == "Pistol")
{
Shoot();
}
}
//Check if aim button down
if (Input.GetButton("Fire2"))
{
if (playerGun.holding == "Pistol")
{
Aim();
}
}
//Check if no longer aiming to reset to normal
if (aimed == true && !(Input.GetButton("Fire2")))
{
Unaim();
}
}
void Shoot()
{
muzzleFlash.Play();
RaycastHit hit;
if(Physics.Raycast(plrCam.transform.position, plrCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Health health = hit.transform.GetComponent<Health>();
if (health != null)
{
health.TakeDamage(damage);
}
//Instantiate the Impact Effect
GameObject IE = Instantiate(impactEffect, hit.point, Quaternion.identity);
Destroy(IE, 1.5f);
}
}
void Aim()
{
aimed = true;
Debug.Log("Aiming");
GPR.gun.transform.position = aimPos.transform.position;
GPR.gun.transform.rotation = Quaternion.Euler(0, 0, plrCam.transform.rotation.z);
}
void Unaim()
{
GPR.gun.transform.position = handPos.transform.position;
Debug.Log("No longer aiming");
aimed = false;
}
}
I fixed my problem by making the gun a child of my camera instead of a child of my player.

Unity Standard assets Cross Platform input not working

I imported Unity Standard Assets cross platform input successfully
In imported cross Platfrom script UnityStandardAssets.CrossCrossPlatformInput is working perfectly
but when i use it in CharacterController2D script that not respoonding
shows errors
unknown package actually namespace in C#
and in file path for standard assets is
Assets\Standard Assets\CrossPlatformInput\Scripts
and CharacterController2D path is
Assets\Scripts
following CharacterController2D script is
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement; // include so we can load new scenes
using UnityStandardAssets.CrossCrossPlatformInput; //even this line shows error
public class CharacterController2D : MonoBehaviour {
// player controls
[Range(0.0f, 10.0f)] // create a slider in the editor and set limits on moveSpeed
public float moveSpeed = 3f;
public float jumpForce = 600f;
// player health
public int playerHealth = 1;
// LayerMask to determine what is considered ground for the player
public LayerMask whatIsGround;
// Transform just below feet for checking if player is grounded
public Transform groundCheck;
// player can move?
// we want this public so other scripts can access it but we don't want to show in editor as it might confuse designer
[HideInInspector]
public bool playerCanMove = true;
// SFXs
public AudioClip coinSFX;
public AudioClip deathSFX;
public AudioClip fallSFX;
public AudioClip jumpSFX;
public AudioClip victorySFX;
// private variables below
// store references to components on the gameObject
Transform _transform;
Rigidbody2D _rigidbody;
Animator _animator;
AudioSource _audio;
// hold player motion in this timestep
float _vx;
float _vy;
// player tracking
bool facingRight = true;
bool isGrounded = false;
bool isRunning = false;
bool canDoubleJump = false;
// store the layer the player is on (setup in Awake)
int _playerLayer;
// number of layer that Platforms are on (setup in Awake)
int _platformLayer;
void Awake () {
// get a reference to the components we are going to be changing and store a reference for efficiency purposes
_transform = GetComponent<Transform> ();
_rigidbody = GetComponent<Rigidbody2D> ();
if (_rigidbody==null) // if Rigidbody is missing
Debug.LogError("Rigidbody2D component missing from this gameobject");
_animator = GetComponent<Animator>();
if (_animator==null) // if Animator is missing
Debug.LogError("Animator component missing from this gameobject");
_audio = GetComponent<AudioSource> ();
if (_audio==null) { // if AudioSource is missing
Debug.LogWarning("AudioSource component missing from this gameobject. Adding one.");
// let's just add the AudioSource component dynamically
_audio = gameObject.AddComponent<AudioSource>();
}
// determine the player's specified layer
_playerLayer = this.gameObject.layer;
// determine the platform's specified layer
_platformLayer = LayerMask.NameToLayer("Platform");
}
// this is where most of the player controller magic happens each game event loop
void Update()
{
// exit update if player cannot move or game is paused
if (!playerCanMove || (Time.timeScale == 0f))
return;
// determine horizontal velocity change based on the horizontal input
_vx = CrossPlatformInputManager.GetAxisRaw ("Horizontal");
// Determine if running based on the horizontal movement
if (_vx != 0)
{
isRunning = true;
} else {
isRunning = false;
}
// set the running animation state
_animator.SetBool("Running", isRunning);
// get the current vertical velocity from the rigidbody component
_vy = _rigidbody.velocity.y;
// Check to see if character is grounded by raycasting from the middle of the player
// down to the groundCheck position and see if collected with gameobjects on the
// whatIsGround layer
isGrounded = Physics2D.Linecast(_transform.position, groundCheck.position, whatIsGround);
///checking if can do double jump or not
if (isGrounded)
{
canDoubleJump = true;
}
// Set the grounded animation states
_animator.SetBool("Grounded", isGrounded);
if(isGrounded && CrossPlatformInputManager.GetButtonDown("Jump")) // If grounded AND jump button pressed, then allow the player to jump
{
doJump ();
}
else if(canDoubleJump && CrossPlatformInputManager.GetButtonDown("Jump"))
{
doJump ();
canDoubleJump = false; //disabling dpuble jump after single jump
}
// If the player stops jumping mid jump and player is not yet falling
// then set the vertical velocity to 0 (he will start to fall from gravity)
if(CrossPlatformInputManager.GetButtonUp("Jump") && _vy>0f)
{
_vy = 0f;
}
// Change the actual velocity on the rigidbody
_rigidbody.velocity = new Vector2(_vx * moveSpeed, _vy);
// if moving up then don't collide with platform layer
// this allows the player to jump up through things on the platform layer
// NOTE: requires the platforms to be on a layer named "Platform"
Physics2D.IgnoreLayerCollision(_playerLayer, _platformLayer, (_vy > 0.0f));
}
// Checking to see if the sprite should be flipped
// this is done in LateUpdate since the Animator may override the localScale
// this code will flip the player even if the animator is controlling scale
void LateUpdate()
{
// get the current scale
Vector3 localScale = _transform.localScale;
if (_vx > 0) // moving right so face right
{
facingRight = true;
} else if (_vx < 0) { // moving left so face left
facingRight = false;
}
// check to see if scale x is right for the player
// if not, multiple by -1 which is an easy way to flip a sprite
if (((facingRight) && (localScale.x<0)) || ((!facingRight) && (localScale.x>0))) {
localScale.x *= -1;
}
// update the scale
_transform.localScale = localScale;
}
// if the player collides with a MovingPlatform, then make it a child of that platform
// so it will go for a ride on the MovingPlatform
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag=="MovingPlatform")
{
this.transform.parent = other.transform;
}
}
// if the player exits a collision with a moving platform, then unchild it
void OnCollisionExit2D(Collision2D other)
{
if (other.gameObject.tag=="MovingPlatform")
{
this.transform.parent = null;
}
}
// do what needs to be done to freeze the player
void FreezeMotion() {
playerCanMove = false;
_rigidbody.isKinematic = true;
}
// do what needs to be done to unfreeze the player
void UnFreezeMotion() {
playerCanMove = true;
_rigidbody.isKinematic = false;
}
// play sound through the audiosource on the gameobject
void PlaySound(AudioClip clip)
{
_audio.PlayOneShot(clip);
}
// public function to apply damage to the player
public void ApplyDamage (int damage) {
if (playerCanMove) {
playerHealth -= damage;
if (playerHealth <= 0) { // player is now dead, so start dying
PlaySound(deathSFX);
StartCoroutine (KillPlayer ());
}
}
}
//Public Jump function
public void doJump()
{
// reset current vertical motion to 0 prior to jump
_vy = 0f;
// add a force in the up direction
_rigidbody.AddForce (new Vector2 (0, jumpForce));
// play the jump sound
PlaySound(jumpSFX);
}
//EnemyJump function
public void EnemyJump()
{
doJump ();
}
// public function to kill the player when they have a fall death
public void FallDeath () {
if (playerCanMove) {
playerHealth = 0;
PlaySound(fallSFX);
StartCoroutine (KillPlayer ());
}
}
// coroutine to kill the player
IEnumerator KillPlayer()
{
if (playerCanMove)
{
// freeze the player
FreezeMotion();
// play the death animation
_animator.SetTrigger("Death");
// After waiting tell the GameManager to reset the game
yield return new WaitForSeconds(2.0f);
if (GameManager.gm) // if the gameManager is available, tell it to reset the game
GameManager.gm.ResetGame();
else // otherwise, just reload the current level
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
public void CollectCoin(int amount) {
PlaySound(coinSFX);
if (GameManager.gm) // add the points through the game manager, if it is available
GameManager.gm.AddPoints(amount);
}
// public function on victory over the level
public void Victory() {
PlaySound(victorySFX);
FreezeMotion ();
_animator.SetTrigger("Victory");
if (GameManager.gm) // do the game manager level compete stuff, if it is available
GameManager.gm.LevelCompete();
}
// public function to respawn the player at the appropriate location
public void Respawn(Vector3 spawnloc) {
UnFreezeMotion();
playerHealth = 1;
_transform.parent = null;
_transform.position = spawnloc;
_animator.SetTrigger("Respawn");
}
}
This is first time that I have used cross platform input
so I don't even know why this error is showing
Sorry to Bother you guys.
I think i found my error in this code
actually i mistakenly write
using UnityStandardAssets.CrossCrossPlatformInput;
instead of
using UnityStandardAssets.CrossPlatformInput;
that's why it's showing error Unknown Namespace Under Standard Unity Assests
Actually I am new to Unity and also new to game development
i think that's why this problem happen
also, you need to use a compiler definition as shown, i was stuck on it for a long time, but found it written in the guidelines that come along with standard asset package..
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
// CROSS_PLATFORM_INPUT
public class Player : MonoBehaviour
{
public float speed = 6f;
Vector2 moveVelocity;
public Rigidbody2D rb;
Vector2 movement;
void Update()
{
Vector2 moveInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
moveVelocity = moveInput * speed;
}
void FixedUpdate()
{
rb.MovePosition(rb.position + moveVelocity * Time.fixedDeltaTime);
}
public void Up()
{
FixedUpdate();
}
private void OnTriggerEnter2D(Collider2D target)
{
if (target.tag == "Enemy")
{
GameManager.instance.PlayerDied();
Debug.Log("ok");
}
if (target.tag == "Finish")
{
Debug.Log("ok");
GameManager.instance.PlayerWin();
}
}
}

2d standard assets prefab characterRobotBoy jumped into the boxCollider

I am using the standard 2d assets to learn developing 2d game with Unity, and I place a sprite with box-collider-2d, and choose the default standard assets CharacterRobotBoy to mess around with.
But I find that if I jumped and it's highly likely that the character will jump into the sprite which was intended to be made as a ground, but this will not happen every time. hope could get some help with that.
find the problem hard to describe and upload a video on youtue
EDIT
will just paste the script from the demo asset as required.
File PlatformerCharacter2D.cs
using System;
using UnityEngine;
namespace UnityStandardAssets._2D
{
public class PlatformerCharacter2D : MonoBehaviour
{
[SerializeField] private float m_MaxSpeed = 10f; // The fastest the player can travel in the x axis.
[SerializeField] private float m_JumpForce = 400f; // Amount of force added when the player jumps.
[Range(0, 1)] [SerializeField] private float m_CrouchSpeed = .36f; // Amount of maxSpeed applied to crouching movement. 1 = 100%
[SerializeField] private bool m_AirControl = false; // Whether or not a player can steer while jumping;
[SerializeField] private LayerMask m_WhatIsGround; // A mask determining what is ground to the character
private Transform m_GroundCheck; // A position marking where to check if the player is grounded.
const float k_GroundedRadius = .2f; // Radius of the overlap circle to determine if grounded
private bool m_Grounded; // Whether or not the player is grounded.
private Transform m_CeilingCheck; // A position marking where to check for ceilings
const float k_CeilingRadius = .01f; // Radius of the overlap circle to determine if the player can stand up
private Animator m_Anim; // Reference to the player's animator component.
private Rigidbody2D m_Rigidbody2D;
private bool m_FacingRight = true; // For determining which way the player is currently facing.
private void Awake()
{
// Setting up references.
m_GroundCheck = transform.Find("GroundCheck");
m_CeilingCheck = transform.Find("CeilingCheck");
m_Anim = GetComponent<Animator>();
m_Rigidbody2D = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
m_Grounded = false;
// The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
// This can be done using layers instead but Sample Assets will not overwrite your project settings.
Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
m_Grounded = true;
}
m_Anim.SetBool("Ground", m_Grounded);
// Set the vertical animation
m_Anim.SetFloat("vSpeed", m_Rigidbody2D.velocity.y);
}
public void Move(float move, bool crouch, bool jump)
{
// If crouching, check to see if the character can stand up
if (!crouch && m_Anim.GetBool("Crouch"))
{
// If the character has a ceiling preventing them from standing up, keep them crouching
if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround))
{
crouch = true;
}
}
// Set whether or not the character is crouching in the animator
m_Anim.SetBool("Crouch", crouch);
//only control the player if grounded or airControl is turned on
if (m_Grounded || m_AirControl)
{
// Reduce the speed if crouching by the crouchSpeed multiplier
move = (crouch ? move*m_CrouchSpeed : move);
// The Speed animator parameter is set to the absolute value of the horizontal input.
m_Anim.SetFloat("Speed", Mathf.Abs(move));
// Move the character
m_Rigidbody2D.velocity = new Vector2(move*m_MaxSpeed, m_Rigidbody2D.velocity.y);
// If the input is moving the player right and the player is facing left...
if (move > 0 && !m_FacingRight)
{
// ... flip the player.
Flip();
}
// Otherwise if the input is moving the player left and the player is facing right...
else if (move < 0 && m_FacingRight)
{
// ... flip the player.
Flip();
}
}
// If the player should jump...
if (m_Grounded && jump && m_Anim.GetBool("Ground"))
{
// Add a vertical force to the player.
m_Grounded = false;
m_Anim.SetBool("Ground", false);
m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce));
}
}
private void Flip()
{
// Switch the way the player is labelled as facing.
m_FacingRight = !m_FacingRight;
// Multiply the player's x local scale by -1.
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
}
Script Platformer2DUserControl.cs
using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
namespace UnityStandardAssets._2D
{
[RequireComponent(typeof (PlatformerCharacter2D))]
public class Platformer2DUserControl : MonoBehaviour
{
private PlatformerCharacter2D m_Character;
private bool m_Jump;
private void Awake()
{
m_Character = GetComponent<PlatformerCharacter2D>();
}
private void Update()
{
if (!m_Jump)
{
// Read the jump input in Update so button presses aren't missed.
m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
}
}
private void FixedUpdate()
{
// Read the inputs.
bool crouch = Input.GetKey(KeyCode.LeftControl);
float h = CrossPlatformInputManager.GetAxis("Horizontal");
// Pass all parameters to the character control script.
m_Character.Move(h, crouch, m_Jump);
m_Jump = false;
}
}
}

Categories

Resources