using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum PrimitiveType
{
None,
Ball,
Box
}
///
/// 物理碰撞体基类
/// 对于格斗游戏来说只需要Box和Ball两种
///
public abstract class PhysicsPrimitive : MonoBehaviour
{
public virtual PrimitiveType Type
{
get
{
return PrimitiveType.None;
}
}
///
/// 世界坐标,物理模拟是在世界空间,本地坐标没有意义
///
public Vector3 Position
{
get
{
Vector3 euler = Quaternion.ToEulerAngles(transform.rotation);
euler.y = Mathf.Rad2Deg * euler.y;
Vector3 res = m_Center;
res.x = (euler.y > 0 && euler.y <= 180) ? -res.x : res.x;
res = transform.position + res;
return res;
}
}
[SerializeField]
///
/// 这个primitive是否参与物理计算,用来快速给物体取消和恢复重力影响
///
protected bool m_IsActive;
public bool IsActive
{
get
{
return m_IsActive;
}
}
///
/// 唯一ID
///
protected int m_ID;
public int ID
{
get
{
return m_ID;
}
}
[Tooltip("给primitive分组,决定大组和大组之间是否有碰撞检测")]
[SerializeField]
protected PhysicsGroup m_Group;
public PhysicsGroup Group
{
get
{
return m_Group;
}
}
[Tooltip("给primitive一个标记,表明它的从属关系。帮助做hitbox和hurtbox")]
[SerializeField]
protected PhysicsTag m_Tag;
public PhysicsTag Tag
{
get
{
return m_Tag;
}
}
[Tooltip("同一个标签的没有碰撞检测")]
[SerializeField]
protected string m_Label;
public string Label
{
get
{
return m_Label;
}
}
[Tooltip("单个碰撞体的描述(名称),作为标识用来识别")]
[SerializeField]
protected string m_Title;
public string Title
{
get
{
return m_Title;
}
}
[SerializeField]
protected string m_Desc;
public string Desc
{
get
{
return m_Desc;
}
}
///
/// 初始化,设置一些公共数据
///
protected void OnInit()
{
m_ID = UIDManager.Acquire();
PhysicsWorld.Instance.AddPrimitive(this);
}
protected Color Color_Green = new Color(0, 1, 0, 0.5f);
[SerializeField]
protected Color m_HintColor = new Color(0, 0, 0, 0.5f);
[Tooltip("Physics body, leave blank and primitive will be static.")]
[SerializeField]
protected PhysicsBody m_Body;
public PhysicsBody Body
{
get
{
return m_Body;
}
}
///
/// 中心点在本地空间的位置
///
public Vector3 m_Center;
///
/// 边界:左、右、上、下
///
public Vector4 Bound
{
get
{
Vector4 bound = new Vector4();
if(this is PhysicsBox)
{
PhysicsBox box = this as PhysicsBox;
bound.x = box.Left;
bound.y = box.Right;
bound.z = box.Top;
bound.w = box.Bottom;
}
else if(this is PhysicsBall)
{
PhysicsBall ball = this as PhysicsBall;
bound.x = ball.Position.x - ball.Radius;
bound.y = ball.Position.x + ball.Radius;
bound.z = ball.Position.y + ball.Radius;
bound.w = ball.Position.y - ball.Radius;
}
return bound;
}
}
public bool IsOnGround
{
get
{
if (Mathf.Approximately(Bound.w, PhysicsWorld.Ground))
return true;
return Bound.w <= PhysicsWorld.Ground;
}
}
public bool IsInAir
{
get
{
//return Bound.w > PhysicsWorld.Ground;
return !IsOnGround;
}
}
}