Player is forced up when moving against the enemy
So I have an issue in a first person 3D game, in which the player is controlled through modifying the transformation, and enemies that run of course with the Navmesh, and have Rigidbodies. The problem is that if you walk up to an enemy and keep holding the move key in that direction, you are forced up and walk over the enemy. I have tried disabling "Is Kinematic" in the Rigidbodies of the enemies, however, when the enemies all bunch up they push each other around and it looks really silly.
This is my move script for those who want a reference.
using UnityEngine;
using System.Collections;
public class player_MoveScript : MonoBehaviour {
public float speed;
public float speedSetRun = 2f;
public float speedSetWalk = 1f;
public float speedCrouchChange = 0.5f;
public float speedCrawlChange = 0.3f;
public float jumpSpeed = 8f;
public float gravity = 20f;
private float speedSet; // Speed set based on running or walking
private float speedStance; // Speed modifier based on stance
public float crouchSpeed = 1f;
public float crouchDistance = 0.7f;
public float crouchGoTo; // The set height the player will crouch to
public player_CrouchHeight crouchHeight; // This is used to detect if there are any objects above the player so they don't clip into it when the raise their stance
public float horizontalRotation = 0f;
public float lookSpeed = 5f;
public float leanSpeedLimit = 1f;
public bool isRunning = true;
public bool isMoving = false;
public bool isCrouched = false;
public bool isChangingStance = false; // True when the player is moving up or down from a crouch position
//public bool isCrouchedTable = false; // Is true when the player is near a table they can go under
//public bool isMovingUnderTable = false; // Is true when the player is under the table.
public bool isCrawling = false;
public float crawlDistance = 0.4f;
// IN THE FUTURE, PUT IN A BOOL IN THE GAME MANAGER THAT WILL MAKE IT OPTIONAL IF YOU HOLD TO CRAWL OR
// HAVE A SEPARATE BUTTON
public float crawlHoldTimerSet = 0.4f;
private float crawlHoldTimer;
private float crawlHoldTimerDelaySet = 0.1f;
private float crawlHoldTimerDelay;
public bool isClimbing = false;
public Game_Manager gameManager;
public Player_Interact player_Interact;
public Vector3 moveDirection = Vector3.zero;
void Awake()
{
gameManager = GameObject.FindGameObjectWithTag("GameManager").GetComponent<Game_Manager>();
crouchHeight = GameObject.FindGameObjectWithTag ("CrouchHeight").GetComponent<player_CrouchHeight> ();
crouchGoTo = crouchDistance;
speed = speedSetRun;
crawlHoldTimer = crawlHoldTimerSet;
speedSet = speedSetRun;
speedStance = 0f;
player_Interact = GameObject.FindGameObjectWithTag ("MainCamera").GetComponent<Player_Interact> ();
}
void Update ()
{
speed = speedSet - speedStance;
if(Input.GetKeyDown(KeyCode.LeftShift))
{
speedSet = speedSetWalk;
isRunning = false;
}
else if(Input.GetKeyUp (KeyCode.LeftShift))
{
speedSet = speedSetRun;
isRunning = true;
}
CharacterController controller = GetComponent<CharacterController>();
horizontalRotation = Input.GetAxis ("Mouse X") * lookSpeed;
transform.Rotate (0, horizontalRotation, 0);
if(controller.isGrounded) // This will run so long as the player is touching the ground. Note ONLY USE COMMANDS that ABSOLUTELY require the player to be on the ground. At the moment, isGrounded isn't 100% reliable.
{
float inX = Input.GetAxis ("Horizontal");
float inY = Input.GetAxis ("Vertical");
//float mX = Input.GetAxis ("Mouse X");
if(inY >= leanSpeedLimit || inY <= -leanSpeedLimit || inX >= leanSpeedLimit || inX <= -leanSpeedLimit)
{
isMoving = true;
}
else
{
isMoving = false;
}
if(!isClimbing)
{
moveDirection = new Vector3(inX * speed,0,inY * speed);
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
}
else
{
moveDirection = Vector3.zero;
}
if (Input.GetButton("Jump") && !isCrawling)
{
moveDirection.y = jumpSpeed;
}
}
else
{
isMoving = false;
}
if(Input.GetButton("Crouch") && !isCrawling)
{
if(crawlHoldTimerDelay <= 0)
{
crawlHoldTimer -= Time.deltaTime;
}
else
{
crawlHoldTimerDelay -= Time.deltaTime;
}
}
else
{
crawlHoldTimer = crawlHoldTimerSet;
crawlHoldTimerDelay = crawlHoldTimerDelaySet;
}
// These will determine whether the player is already crouching, and if so, what direction they will be now going in the crouch. If not, it will start the crouch movement.
// This is for putting the playing from standing to crouching
if(Input.GetButtonDown("Crouch") && !isChangingStance && !isCrouched && !isCrawling)
{
crouchGoTo = crouchDistance;
isChangingStance = true;
}
// This is for putting the player from crouching to standing
else if(Input.GetButtonUp("Crouch") && !isChangingStance && (isCrouched && crawlHoldTimer == crawlHoldTimerSet) && crouchHeight.objectCount == 0)
{
crouchGoTo = 1f;
isChangingStance = true;
}
// For putting the player from crawling to crouching
else if(Input.GetButtonDown("Crouch") && !isChangingStance && isCrawling && crouchHeight.objectCount == 0)
{
crouchGoTo = crouchDistance;
isChangingStance = true;
}
// For putting the player into a crawling position
else if(!isCrawling && crawlHoldTimer <= 0f)
{
isChangingStance = true;
crawlHoldTimer = crawlHoldTimerSet;
crawlHoldTimerDelay = crawlHoldTimerDelaySet;
crouchGoTo = crawlDistance;
}
// This will control the actual crouching movement.
if(isChangingStance == true)
{
// if(!isCrouched && !isCrawling && this.transform.localScale.y != crouchGoTo)
// {
float getDown = Mathf.MoveTowards(this.transform.localScale.y,crouchGoTo,Time.deltaTime * (crouchSpeed * 5f));
// getDown is the numeric measurement for the smooth movement down or up
this.transform.localScale = new Vector3(1f,getDown,1f);
player_Interact.crouchDeform = getDown;
// }
// This is the state for when the player is in a crouching position
if(this.transform.localScale.y == crouchGoTo && crouchGoTo == crouchDistance)
{
isCrouched = true;
isCrawling = false;
isChangingStance = false;
speedStance = speedCrouchChange;
}
// This is the state for when the player is in a standing position
else if(this.transform.localScale.y == 1f && crouchGoTo == 1f)
{
isCrouched = false;
isCrawling = false;
isChangingStance = false;
speedStance = 0f;
}
// This is the state for when the player is in a crawling postion
else if(this.transform.localScale.y == crawlDistance && crouchGoTo == crawlDistance)
{
isCrouched = false;
isCrawling = true;
isChangingStance = false;
speedStance = speedCrawlChange;
}
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move (moveDirection * Time.deltaTime);
}
}
Here is a hackish way : simply add a box colider above the enemy then the player will hit the colider and not continue up
In addition to the hack mentioned about in Survival Shooter tutorial Har$$anonymous$$g Enemies part http://unity3d.com/learn/tutorials/projects/survival-shooter/har$$anonymous$$g-enemies?playlist=17144 or in previous one there is detailed info on the topic.