unity 一直困扰我的问题,我在玩家角色使用character controller时候,剩下所有怪物都是碰撞体+刚体
如果有多个怪物例如10个20个,向你冲过来,如果一直冲,发生碰撞,这时候玩家特别容易跑到了怪物头顶
或者你像怪物移动的时候,也特别容易到怪物头顶。
我在设置character controller 尝试了修改所有参数,例如 限制斜度 偏移量 蒙皮 最小移动距离,哪怕改成0我都测试过了
还是不行,还是容易跑到怪物头顶上去,
我现在像请教如何解决这个问题?
1.不可以推荐我不使用character controller(我也会,不用你说,我需要的是用character controller如何解决)
2.怪物必须使用刚体+碰撞体,(不要给我提其他方法)
3.不要想着修改怪物移动逻辑,因为在运行当中会出现各种情况,一定会发生碰撞。(放弃你聪明的大脑在这个位置)
4.在只处理character controller这个前提下,如何解决这个问题
玩家代码非常简单
private CharacterController _player;
// Start is called before the first frame update
void Start()
{
_player = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
var horizontalInput = Input.GetAxis("Horizontal");
var VerticalInput = Input.GetAxis("Vertical");
var dir = new Vector3(horizontalInput, 0, VerticalInput).normalized;
_player.SimpleMove(dir * (Time.deltaTime * 3000));
}
怪物代码更简单,就是向玩家移动
```c#
private Rigidbody _rigidbody;
public Transform player;
// Start is called before the first frame update
void Start()
{
_rigidbody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
var dir = ( player.position - transform.position).normalized;
_rigidbody.position = transform.position + dir * Time.deltaTime * 50f;
}
重点:不要像大聪明一样,让我是用其他的控制器,不要像大聪明一样修改怪物逻辑
基于new bing部分指引作答:
根据您的要求,您可以尝试在Character Controller上使用一些附加的技巧来解决这个问题。以下是几种可能的解决方案:
1、使用Raycast检测碰撞:在Character Controller上使用Raycast来检测前方是否有碰撞物体。如果检测到碰撞物体,可以停止移动或采取其他适当的行动。这样可以避免角色穿过怪物。
void Update()
{
var horizontalInput = Input.GetAxis("Horizontal");
var verticalInput = Input.GetAxis("Vertical");
var dir = new Vector3(horizontalInput, 0, verticalInput).normalized;
RaycastHit hit;
if (Physics.Raycast(transform.position, dir, out hit, 1f))
{
// 停止移动或采取其他适当的行动
}
else
{
_player.SimpleMove(dir * (Time.deltaTime * 3000));
}
}
2、使用SphereCast检测碰撞:类似于上述的Raycast方法,您可以使用SphereCast来检测角色前方的碰撞物体。这对于检测更大范围的碰撞可能更有效。
void Update()
{
var horizontalInput = Input.GetAxis("Horizontal");
var verticalInput = Input.GetAxis("Vertical");
var dir = new Vector3(horizontalInput, 0, verticalInput).normalized;
RaycastHit hit;
float sphereRadius = 0.5f; // 根据实际情况调整球体半径
if (Physics.SphereCast(transform.position, sphereRadius, dir, out hit, 1f))
{
// 停止移动或采取其他适当的行动
}
else
{
_player.SimpleMove(dir * (Time.deltaTime * 3000));
}
}
这些方法可以帮助您在使用Character Controller时避免角色穿过怪物。您可以根据实际需求调整射线或球体的参数以获得最佳结果。请注意,这些解决方案可能需要根据您的场景和需求进行进一步调整和优化。
1. 将Player的Collider大小缩小为不与Monster重叠。
2. 使用`CharacterController.Move()`替换`CharacterController.SimpleMove()`。
3. 在`CharacterController.Move()`之后,使用`Physics.SphereCast()`或`Physics.CapsuleCast()`检测玩家与怪物之间是否有障碍物,若有,则向移动方向施加反向力以避免穿透。
修改你上面提供的代码:
private CharacterController _player;
private Vector3 _moveDirection = Vector3.zero;
public float playerSpeed = 5f;
public float castRadius = 1f;
public float castDistance = 1f;
void Start()
{
_player = GetComponent<CharacterController>();
}
void Update()
{
var horizontalInput = Input.GetAxis("Horizontal");
var VerticalInput = Input.GetAxis("Vertical");
_moveDirection = new Vector3(horizontalInput, 0, VerticalInput).normalized;
_moveDirection *= playerSpeed;
// 计算玩家的新位置
_player.Move(_moveDirection * Time.deltaTime);
// 检测是否有障碍物
RaycastHit hit;
if (Physics.SphereCast(transform.position, castRadius, _moveDirection, out hit, castDistance))
{
Vector3 reflectDirection = Vector3.Reflect(_moveDirection, hit.normal);
_player.Move(reflectDirection * Time.deltaTime);
}
}
使用了`SphereCast()`函数来检测玩家与怪物之间是否有障碍物,如果有,则进行反向操作以避免穿透。