我正在研究自定义物理行为并使用CircleCast来确定是否存在地面/墙壁。但在某些情况下,CircleCast会通过对撞机而不会碰到它。似乎问题出现在起始圆圈与碰撞器重叠一点时。
我该如何解决,或者我做错了什么?
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public Rigidbody2D ball;
public CircleCollider2D circleCollider;
public float speed;
public LayerMask layerMask;
public bool grounded;
public Transform graphics;
public Transform startCast, endCast;
public GameObject tempBall;
private int maxPathSize = 5;
private Queue<GameObject> path;
private float realRadius;
private Vector2 roughDirection;
private float rayLength;
private Vector2 realDirection;
private Vector2 gravity;
private Vector2 preferedDirectionOfMove;
// Use this for initialization
void Start()
{
path = new Queue<GameObject>();
realRadius = circleCollider.radius * ball.transform.localScale.x;
rayLength = realRadius + (realRadius / 10);
gravity = new Vector2(0, -9.81f);
}
// Update is called once per frame
void Update()
{
// if (Time.frameCount % 10 == 0)
{
preferedDirectionOfMove = gravity;
if (Input.GetKey(KeyCode.RightArrow) && grounded)
{
preferedDirectionOfMove = ball.transform.right;
}
if (Input.GetKey(KeyCode.LeftArrow) && grounded)
{
preferedDirectionOfMove = -ball.transform.right;
}
Move();
}
}
void Move()
{
if (grounded && preferedDirectionOfMove == gravity)
return;
Debug.Log("***********");
AddToPath(ball.position);
realDirection = (preferedDirectionOfMove * speed * Time.deltaTime);
Color color = Color.black;
Vector2 oldPos = ball.position;
Color colorX = RandomColor();
DrawX(ball.position, colorX, 0.2f, 1, 0.5f);
RaycastHit2D hit = Physics2D.CircleCast(ball.position, realRadius, realDirection.normalized, realDirection.magnitude, layerMask);
if (hit)
{
DrawX(hit.point, colorX, 0.2f, 0.5f, 1.5f);
SetAngle(hit);
ball.position = GetNewPosition(hit);
grounded = true;
Debug.Log("grounded: " + true);
}
else
{
ball.position += realDirection;
DrawX(ball.position, colorX, 0.2f, 0.5f, 1.5f);
Debug.Log("grounded: " + false);
color = Color.red;
grounded = false;
}
Debug.DrawLine(oldPos, ball.position, color, 1);
}
void AddToPath(Vector2 position)
{
GameObject go = Instantiate(tempBall, position, Quaternion.identity) as GameObject;
if (path.Count >= 5)
{
Destroy(path.Dequeue());
}
path.Enqueue(go);
}
void DrawX(Vector2 position, Color color, float size, float duration, float shape)
{
Debug.DrawLine(position - Vector2.one * (size / 2f), position + Vector2.one * (size / 2f), color, duration);
Debug.DrawLine(position + new Vector2(-1 * shape, 1) * (size / 2f), position + new Vector2(1, -1 * shape) * (size / 2f), color, duration);
}
Color RandomColor()
{
return new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f), 1);
}
Vector2 GetNewPosition(RaycastHit2D hit)
{
return hit.point + ((Vector2)hit.normal * realRadius);
}
void SetAngle(RaycastHit2D hit)
{
float angle2 = AngleAtan2(hit.normal, Vector2.right);
ball.MoveRotation(angle2);
}
float AngleAtan2(Vector2 from, Vector2 to)
{
return Mathf.Rad2Deg * (Mathf.Atan2(to.y, to.x) - Mathf.Atan2(from.x, from.y));
}
void OnCollisionEnter2D(Collision2D collision)
{
Debug.Log("collision enter");
}
}
答案 0 :(得分:1)
当铸造对象与起始位置处的对撞机重叠时,未注册命中是默认行为。要解决此问题,请检查项目设置中物理2D管理器中的查询开始在碰撞器中框。
如果您不希望所有查询出现此行为,则可能需要查看光线投射,因为光线投射在对撞机中启动的可能性要小得多。如果您决定使用射线投射,请取消上面的框并开始射线 你的球员/球的对手本身。这样你就可以确定你永远不会错过任何命中,因为射线在违规对撞机内部开始。