Rigidbody.Is Kinematic和碰撞体

本文介绍了Unity中的物理系统,包括Rigidbody组件的IsKinematic属性、各种类型的碰撞器(如BoxCollider和SphereCollider)、物理材质的配置方法以及触发器的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Rigidbody组件拥有一个Is Kinematic的属性,该属性可以将其从引擎的控制中移除,从而可以用脚本控制GO的运动。注意:尽量不要使用脚本控制该属性的开关。

Colliders(碰撞器)

Colliders组件为物理碰撞定义了一个物体的形状。它不需要完全符合GO的网格形状;事实上,大致相似在游戏中更加有效率。
UNITY中最简单的几种碰撞器: Box Collider, Sphere Collider 和Capsule Collider;2D碰撞器:Collider 2D 和 Circle Collider 2D。
有时候需要以组合的形式附加到物体上,这种形式可以保持较低的处理器开销,也增加一定的灵活性;但它们应该只有一个Rigidbody组件在父物体上。
那组合的碰撞器也不能满足我们的需求,这就需要 Mesh Collider;它可以精确的匹配对象的网格形状。但不要经常使用,它对性能的要求挺高。需要碰撞检测的时候可以把它设置为Convex,它一般被使用在几何图形上。
物体可以被单独添加一个碰撞器(可以没有刚体),不过一般这个物体是静态的。

Physics materials(物理材质)

物体之间相互碰撞的时候,物体表面会模拟它身上材质的属性,比如冰块,篮球等;物体的摩擦系数,弹性系数可以用物理材质来配置。

Triggers(触发器)

通过脚本可以通过OnCollisionEnter启动检测什么时候发生的碰撞,也可以通过修改碰撞器上Is Trigger,来启动是否需要碰撞检测。启动之后会允许碰撞物体穿过,穿过的时候将调用物体脚本的OnTriggerEnter函数。

转载于:https://www.cnblogs.com/mcyushao/p/9597354.html

using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UnityEngine.UI; using UnityEngine.AI; [RequireComponent(typeof(Rigidbody))] public class EnemyRun : MonoBehaviour { private Transform player; private Rigidbody rb; private Animator animator; private NavMeshAgent agent; private Vector3 velocity; public float gravity = -99f; public float groundCheckDistance = 0.4f; public LayerMask groundMask; private Slider hpSlider; private float Hp = 100f; private bool isGrounded; private Vector3 lastValidPosition; void Start() { player = GameObject.FindWithTag("Player").GetComponent<Transform>(); hpSlider = transform.Find("Canvas/Slider").GetComponent<Slider>(); animator = GetComponent<Animator>(); rb = GetComponent<Rigidbody>(); agent = GetComponent<NavMeshAgent>(); rb.constraints = RigidbodyConstraints.FreezeRotation; lastValidPosition = transform.position; } void Update() { hpSlider.value = Hp; if (Hp <= 0) { agent.enabled = false; rb.isKinematic = true; animator.SetBool("isDeath", true); return; } if (agent.isOnNavMesh) { lastValidPosition = transform.position; } if (agent.enabled && player != null) { agent.SetDestination(player.position); } } public void FixedUpdate() { isGrounded = Physics.CheckSphere(transform.position, groundCheckDistance, groundMask); if (isGrounded && velocity.y < 0) { velocity.y = -2f; } velocity.y += gravity * Time.deltaTime; if(!agent.enabled) { rb.velocity = new Vector3(rb.velocity.x, velocity.y, rb.velocity.z); } } public void OnCollisionEnter(Collision collision) { if (Hp <= 0) return; TakeDamage(0f); if (collision.collider.CompareTag ("shot")) { TakeDamage(6f); } if (collision.collider.CompareTag("ricochet")) { TakeDamage(9f); } if (collision.collider.CompareTag("penetration")) { TakeDamage(18f); } } public void TakeDamage(float damge) { if (Hp <= 0) return; Hp -= damge; agent.enabled = false; rb.isKinematic = false; rb.AddForce((Vector3.up + Random.insideUnitSphere * 0.3f) * 3f, ForceMode.Impulse); CancelInvoke(nameof(ResetNavigation)); Invoke(nameof(ResetNavigation), 0.5f); } void ResetNavigation() { rb.velocity = Vector3.zero; rb.angularVelocity = Vector3.zero; if (!agent.isOnNavMesh) { if (NavMesh.SamplePosition(lastValidPosition, out NavMeshHit hit, 5f, NavMesh.AllAreas)) { transform.position = hit.position; agent.Warp(hit.position); } else { Debug.LogWarning("无法找到有效导航位置,敌人将被销毁"); Destroy(gameObject); } } rb.isKinematic = true; agent.enabled = true; } } 敌人被击中后每次都掉出地图,怎么解决
最新发布
05-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值