在开发Unity游戏Demo的过程中,我遇到了一个具体需求:
当敌人与玩家发生碰撞时,玩家应该沿碰撞面法线方向受到一个推力。
通常情况下,Unity中的CharacterController
组件无法直接实现这一效果,因此我探索了一种替代方法来模拟这种力的效应。
问题: 在Unity中如何在玩家与敌人发生碰撞时,垂直于接触面向玩家施加一个力?
解决方案: 可以通过碰撞信息中的Collision
类的contacts
数组获取法线,利用该法线与力的乘积通过Rigidbody.AddForce
方法施加力。
实现代码示例:
using UnityEngine;
public class Controller : MonoBehaviour
{
public float damage = 10.0f;
public float attackForce = 1000f;
private void OnCollisionEnter(Collision collision)
{
Controller player = collision.gameObject.GetComponent<Controller>();
if (player != null)
{
player.TakeDamage(damage);
if (collision.contacts.Length > 0)
{
ContactPoint contact = collision.contacts[0];
Vector3 normal = contact.normal;
Rigidbody rb = player.GetComponent<Rigidbody>();
if (rb != null)
{
rb.AddForce(normal * attackForce);//刚体
}
}
}
}
}
问题:
CharacterController
组件是独立于Unity物理引擎的,它处理移动和碰撞而不受标准物理规则的影响。为了在使用CharacterController
时模拟物理效果,我们可以采用以下的代码结构。
模拟力代码:
public class PlayerController : MonoBehaviour
{
private CharacterController controller;
public float speed = 5.0f;
public Vector3 impactForce;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
if (impactForce.magnitude > 0.1f)
{
controller.Move(impactForce * Time.deltaTime);
impactForce = Vector3.Lerp(impactForce, Vector3.zero, Time.deltaTime);
}
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
controller.Move(move * speed * Time.deltaTime);
}
public void AddImpact(Vector3 force)
{
impactForce += force;
}
}
此时, AddForce
和 AddImpact
等效,可以在 CharacterController
中调用相关方法