Issues with manual collision detection involving updates...

My manual collision system involves four scripts attached to four triggers around the character object, which stop movement in that direction when colliding with a “wall”-tagged object. The game is grid-based, so this is a good way to maintain said collision. When the character walks towards a wall, he stops, as I have scripted it. However, when his side is touching the wall and he rotates to face it, the trigger in front does not detect the wall, and the player can walk through the wall. Is there a possible way to fix this? Does it perhaps have to do with updates?

I have:

  • Made sure they all have RigidBody attached to them
  • Referred to documentation for this issue

Here is my movement script:

using UnityEngine;
using System.Collections;

public class PlayerMovement : MonoBehaviour {

	public static bool CanMoveForward;
	public static bool CanMoveBackward;
	public static bool CanMoveLeft;
	public static bool CanMoveRight;

	//Translation:
	float movSpeed = 4.0f;
	Vector3 pos;
	Transform tr ;
	public static bool moving = false;
	
	//Rotation:
	public static bool rotating = false;
	public float rotSpeed = 360f;
	float rotDegrees = 0f;
	Quaternion rotToAngle ;
	
	void Start () {  
		pos = transform.position;
		tr = transform;
//		CanMoveForward = true;
//		CanMoveBackward = true;
//		CanMoveLeft = true;
//		CanMoveRight = true;
	}
	
	// Update is called once per frame
	void Update () {
		Debug.DrawRay(transform.position, transform.forward, Color.red);
		//Input:
		if (!moving && !rotating) {
			if (Input.GetKey(KeyCode.D) && tr.position == pos && CanMoveRight) {
				//pos += Vector3.right;
				pos += transform.right;
				moving=true;
//				print ("MOVE LEFT");
			} else if (Input.GetKey(KeyCode.A) && tr.position == pos && CanMoveLeft) {
				pos += -transform.right;
				moving=true;
//				print ("MOVE RIGHT");
			} else if (Input.GetKey(KeyCode.W) && tr.position == pos && CanMoveForward) {
				pos += transform.forward;
				moving=true;
//				print ("MOVE FORWARD");
			} else if (Input.GetKey(KeyCode.S) && tr.position == pos && CanMoveBackward) {
				pos += -transform.forward;
				moving=true;
//				print ("MOVE BACK");
			} else if (Input.GetKey(KeyCode.Q) && tr.position == pos) {
				rotDegrees -= 90f;
				//rotToAngle = Quaternion.Euler(0, rotDegrees, 0);
				rotToAngle = Quaternion.Euler(0, rotDegrees, 0);
				rotating = true;
//				print ("TURN LEFT");
			} else if (Input.GetKey(KeyCode.E) && tr.position == pos) {
				rotDegrees += 90f;
				//rotToAngle = Quaternion.Euler(0, rotDegrees, 0);
				rotToAngle = Quaternion.Euler(0, rotDegrees, 0);
				rotating = true;
//				print ("TURN RIGHT");
			}
		}


		
		//Translation:
		if (moving) {
			if (Vector3.Distance(transform.position,pos) <0.05f){
				transform.position = pos;
				moving=false;
//				print ("FINISHED MOVE");
			} else {
				transform.position = Vector3.MoveTowards(transform.position, pos, Time.deltaTime * movSpeed);
			}
		}
		
		//Rotation:
		if (rotating) {
			if (Quaternion.Angle(transform.rotation,rotToAngle) <10f) {
				transform.rotation = rotToAngle;
				rotating=false;
//				print ("FINISHED TURN");
			} else {
				transform.rotation = Quaternion.RotateTowards(transform.rotation, rotToAngle, rotSpeed * Time.deltaTime);
			}
		}
	}

}

=======================================

Here are the scripts that control halting movement relative to direction:

using UnityEngine;
using System.Collections;

public class FrontCollisionSystem : MonoBehaviour {

	// Use this for initialization
	void Start () {
		PlayerMovement.CanMoveForward = true;
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	void OnTriggerEnter(Collider other) {
		if(other.CompareTag("wall") && !PlayerMovement.rotating) {
			PlayerMovement.CanMoveForward = false;
		}
	}

	void OnTriggerExit(Collider other) {
		PlayerMovement.CanMoveForward = true;
	}

}

using UnityEngine;
using System.Collections;

public class BackCollisionSystem : MonoBehaviour {

	// Use this for initialization
	void Start () {
		PlayerMovement.CanMoveBackward = true;
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	void OnTriggerEnter(Collider other) {
		if(other.CompareTag("wall") && !PlayerMovement.rotating) {
			PlayerMovement.CanMoveBackward = false;
		}
	}

	void OnTriggerExit(Collider other) {
		PlayerMovement.CanMoveBackward = true;
	}

}

using UnityEngine;
using System.Collections;

public class LeftCollisionSystem : MonoBehaviour {

	// Use this for initialization
	void Start () {
		PlayerMovement.CanMoveLeft = true;
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	void OnTriggerEnter(Collider other) {
		if(other.CompareTag("wall") && !PlayerMovement.rotating) {
			PlayerMovement.CanMoveLeft = false;
		}
	}

	void OnTriggerExit(Collider other) {
		PlayerMovement.CanMoveLeft = true;
	}

}

using UnityEngine;
using System.Collections;

public class RightCollisionSystem : MonoBehaviour {

	// Use this for initialization
	void Start () {
		PlayerMovement.CanMoveRight = true;
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	void OnTriggerEnter(Collider other) {
		if(other.CompareTag("wall") && !PlayerMovement.rotating) {
			PlayerMovement.CanMoveRight = false;
		}
	}

	void OnTriggerExit(Collider other) {
		PlayerMovement.CanMoveRight = true;
	}

}

Thanks in advance! :smiley:

You’ve a lot of code but I may have spotted what your issue is here:

  void OnTriggerEnter(Collider other) {
         if(other.CompareTag("wall") && !PlayerMovement.rotating) {
             PlayerMovement.CanMoveForward = false;
         }
     }

this I believe is where if the player is rotating and up against a wall, I assume the CanMoveForward is not being set to false and thus allowing him to pass through the wall