From ef739e3c4d66007fb9c2ced195edb539eb92f3a4 Mon Sep 17 00:00:00 2001 From: chai Date: Tue, 3 Nov 2020 19:05:55 +0800 Subject: *misc --- Assets/Scripts/Avatar/Abilities/AttackAbility.cs | 2 +- Assets/Scripts/Avatar/Abilities/UberAbility.cs | 12 ++ .../Scripts/Avatar/Abilities/UberAbility.cs.meta | 11 ++ Assets/Scripts/Avatar/AbilitySystem.cs | 19 ++- Assets/Scripts/Avatar/Actions/ActionEffects.meta | 8 + .../Avatar/Actions/ActionSetLocalVelocity.cs | 21 +++ .../Avatar/Actions/ActionSetLocalVelocity.cs.meta | 11 ++ Assets/Scripts/Physics/PhysicsBody.cs | 18 ++ Assets/Scripts/Physics/PhysicsWorld.cs | 183 +++++++++++++-------- Assets/Scripts/Props.meta | 8 + Assets/Scripts/Test/SaionjiUberAbility.cs | 24 +++ Assets/Scripts/Test/SaionjiUberAbility.cs.meta | 11 ++ 12 files changed, 253 insertions(+), 75 deletions(-) create mode 100644 Assets/Scripts/Avatar/Abilities/UberAbility.cs create mode 100644 Assets/Scripts/Avatar/Abilities/UberAbility.cs.meta create mode 100644 Assets/Scripts/Avatar/Actions/ActionEffects.meta create mode 100644 Assets/Scripts/Avatar/Actions/ActionSetLocalVelocity.cs create mode 100644 Assets/Scripts/Avatar/Actions/ActionSetLocalVelocity.cs.meta create mode 100644 Assets/Scripts/Props.meta create mode 100644 Assets/Scripts/Test/SaionjiUberAbility.cs create mode 100644 Assets/Scripts/Test/SaionjiUberAbility.cs.meta (limited to 'Assets/Scripts') diff --git a/Assets/Scripts/Avatar/Abilities/AttackAbility.cs b/Assets/Scripts/Avatar/Abilities/AttackAbility.cs index 38c5d62f..c6e4d21e 100644 --- a/Assets/Scripts/Avatar/Abilities/AttackAbility.cs +++ b/Assets/Scripts/Avatar/Abilities/AttackAbility.cs @@ -105,7 +105,7 @@ public class AttackAbility : AbilityBase hitInfo.AddRecord(avatar); Debug.Log("hit " + avatar.Name); PhysicsBody body = avatar.Body; - body.AddForce(new Vector3(3000, 0, 0)); + body.SetLocalForce(new Vector3(1000, 5000, 0)); if(avatar is ArmorSoldierScript) { ArmorSoldierScript solider = avatar as ArmorSoldierScript; diff --git a/Assets/Scripts/Avatar/Abilities/UberAbility.cs b/Assets/Scripts/Avatar/Abilities/UberAbility.cs new file mode 100644 index 00000000..0a5bb8c5 --- /dev/null +++ b/Assets/Scripts/Avatar/Abilities/UberAbility.cs @@ -0,0 +1,12 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +// 一个角色只能有一个uber ability,用来处理状态的自动切换 +public abstract class UberAbility : AbilityBase +{ + public abstract void OnUpdate(); + + public abstract void OnLateUpdate(); + +} diff --git a/Assets/Scripts/Avatar/Abilities/UberAbility.cs.meta b/Assets/Scripts/Avatar/Abilities/UberAbility.cs.meta new file mode 100644 index 00000000..644a961f --- /dev/null +++ b/Assets/Scripts/Avatar/Abilities/UberAbility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e409e4f283e85841a62293fe96b1cce +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/AbilitySystem.cs b/Assets/Scripts/Avatar/AbilitySystem.cs index 024e73cb..3e2ab838 100644 --- a/Assets/Scripts/Avatar/AbilitySystem.cs +++ b/Assets/Scripts/Avatar/AbilitySystem.cs @@ -22,6 +22,8 @@ public class AbilitySystem private List m_Abilities = new List(); + private UberAbility m_UberAbility; + public AbilitySystem() { } @@ -38,6 +40,11 @@ public class AbilitySystem m_Currrent.OnEnter(); } + public void SetUberAbility(UberAbility ability) + { + m_UberAbility = ability; + } + public void AddAbility(AbilityBase ability) { m_Abilities.Add(ability); @@ -49,7 +56,11 @@ public class AbilitySystem { m_Currrent.OnUpdate(); } - } + if(m_UberAbility != null) + { + m_UberAbility.OnUpdate(); + } + } public void OnLateUpdate() { @@ -57,7 +68,11 @@ public class AbilitySystem { m_Currrent.OnLateUpdate(); } - } + if(m_UberAbility != null) + { + m_UberAbility.OnLateUpdate(); + } + } public void OnHit(PhysicsCollisionInfo info) { diff --git a/Assets/Scripts/Avatar/Actions/ActionEffects.meta b/Assets/Scripts/Avatar/Actions/ActionEffects.meta new file mode 100644 index 00000000..17a426dd --- /dev/null +++ b/Assets/Scripts/Avatar/Actions/ActionEffects.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0b5ccfefc2e6b104a8566f4da9a16c5f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Avatar/Actions/ActionSetLocalVelocity.cs b/Assets/Scripts/Avatar/Actions/ActionSetLocalVelocity.cs new file mode 100644 index 00000000..5e2f62ed --- /dev/null +++ b/Assets/Scripts/Avatar/Actions/ActionSetLocalVelocity.cs @@ -0,0 +1,21 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class ActionSetLocalVelocity : ActionBase +{ + PhysicsBody m_Body; + + Vector3 m_Velocity; + + public ActionSetLocalVelocity(PhysicsBody body, Vector3 localVelocity) + { + m_Body = body; + m_Velocity = localVelocity; + } + + public override void Execute() + { + m_Body.LocalVelocity = m_Velocity; + } +} diff --git a/Assets/Scripts/Avatar/Actions/ActionSetLocalVelocity.cs.meta b/Assets/Scripts/Avatar/Actions/ActionSetLocalVelocity.cs.meta new file mode 100644 index 00000000..0a91e7cd --- /dev/null +++ b/Assets/Scripts/Avatar/Actions/ActionSetLocalVelocity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d0c4285c1d134b045b7a5f323c258579 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Physics/PhysicsBody.cs b/Assets/Scripts/Physics/PhysicsBody.cs index 68f9dec3..b6be778a 100644 --- a/Assets/Scripts/Physics/PhysicsBody.cs +++ b/Assets/Scripts/Physics/PhysicsBody.cs @@ -140,9 +140,27 @@ public sealed class PhysicsBody : MonoBehaviour m_Force += force; } + public void AddLocalForce(Vector3 localForce) + { + m_Force += localToWorldDir(localForce); + } + public void SetForce(Vector3 force) { m_Force = force; } + public void SetLocalForce(Vector3 localForce) + { + m_Force = localToWorldDir(localForce); + } + + public Vector3 localToWorldDir(Vector3 local) + { + if (IsFaceRight) + return local; + else + return new Vector3(-local.x, local.y, local.z); + } + } diff --git a/Assets/Scripts/Physics/PhysicsWorld.cs b/Assets/Scripts/Physics/PhysicsWorld.cs index ba9b1bc1..c5fbe046 100644 --- a/Assets/Scripts/Physics/PhysicsWorld.cs +++ b/Assets/Scripts/Physics/PhysicsWorld.cs @@ -52,10 +52,11 @@ public class PhysicsWorld : Singleton }; private List m_Animators = new List(); +#if UNITY_EDITOR + private List m_Contacts = new List(); +#endif - private List m_Contacts = new List(); - - private List m_CollisionInfo = new List(); + private List m_CollisionInfo = new List(); public const float Ground = 0.1f; @@ -113,13 +114,13 @@ public class PhysicsWorld : Singleton BeforeUpdate(); float preTime = m_TimeCount; m_TimeCount = Time.time; - float dt = m_TimeCount - preTime; - while (dt > 1f / m_UpdateRate) + float deltaTime = m_TimeCount - preTime; + while (deltaTime > 1f / m_UpdateRate) { Tick(); - dt -= 1f / m_UpdateRate; + deltaTime -= 1f / m_UpdateRate; } - m_TimeCount -= dt; + m_TimeCount -= deltaTime; AfterUpdate(); } @@ -137,7 +138,8 @@ public class PhysicsWorld : Singleton public void DrawGizmos() { - if (m_Contacts.Count == 0) +#if UNITY_EDITOR + if (m_Contacts.Count == 0) return; for(int i = 0; i < m_Contacts.Count; ++i) @@ -145,7 +147,8 @@ public class PhysicsWorld : Singleton Vector3 center = m_Contacts[i]; Gizmos.DrawSphere(center, 0.05f); } - } +#endif + } void Tick() @@ -171,35 +174,39 @@ public class PhysicsWorld : Singleton // 更新物理系统 void UpdatePrimitives(float deltaTime) { - m_Contacts.Clear(); +#if UNITY_EDITOR + m_Contacts.Clear(); +#endif - PhysicsCollisionInfo info = new PhysicsCollisionInfo(); + PhysicsCollisionInfo info = new PhysicsCollisionInfo(); - // 处理动力学 - for(int i = 0; i < m_Primitives.Count; ++i) - { - PhysicsPrimitive prim = m_Primitives[i]; - HandleDynamics(prim, deltaTime); - } + // 1) 处理刚体的动力学 + for (int i = 0; i < m_Primitives.Count; ++i) + { + PhysicsPrimitive prim = m_Primitives[i]; + PhysicsBody body = prim.Body; + if (body == null) + continue; + HandleDynamics(prim, deltaTime); + } - // 处理碰撞 - int groupCount = (int)PhysicsGroup.GroupCount; - for (int i = 0; i < m_Primitives.Count; ++i) + // 2) 处理碰撞 + for (int i = 0; i < m_Primitives.Count; ++i) { PhysicsPrimitive prim1 = m_Primitives[i]; if (!prim1.IsActive) continue; + for (int j = i + 1; j < m_Primitives.Count; ++j) { PhysicsPrimitive prim2 = m_Primitives[j]; - // group int minGroup = Mathf.Min((int)prim1.Group, (int)prim2.Group); int maxGroup = Mathf.Max((int)prim1.Group, (int)prim2.Group); - if (m_CollisionTable[minGroup * groupCount + groupCount - maxGroup - 1] == 0) + int index = minGroup * (int)PhysicsGroup.GroupCount + (int)PhysicsGroup.GroupCount - maxGroup - 1; + if (m_CollisionTable[index] == 0) continue; - // label if (prim1.Label == prim2.Label) continue; @@ -208,96 +215,128 @@ public class PhysicsWorld : Singleton SolveCollision(prim1, info, deltaTime); SolveCollision(prim2, info, deltaTime); m_CollisionInfo.Add(info); - m_Contacts.Add(info.contact); - } + +#if UNITY_EDITOR + m_Contacts.Add(info.contact); +#endif + } } } - } - //没有physics body的primitive将不会被移动,只有那些绑定了physics body的会被施加物理效果,比如角色身体、物品 - void HandleDynamics(PhysicsPrimitive prim, float dt) + // 3) 处理刚体的约束,必须在最后处理 + for (int i = 0; i < m_Primitives.Count; ++i) + { + PhysicsPrimitive prim = m_Primitives[i]; + PhysicsBody body = prim.Body; + if (body == null) + continue; + HandleConstrain(prim, deltaTime); + } + + } + + /// + /// 处理有物体的动力学运动 + /// + /// + /// + void HandleDynamics(PhysicsPrimitive prim, float deltaTime) { PhysicsBody body = prim.Body; if (body == null) return; - if (!body.UseGravity) - return; Vector3 position = body.transform.position; - Vector3 velocity = body.Velocity; - velocity += m_Gravity * dt; - body.Velocity = velocity; - // impluse = d(mv) = m*dv - Vector3 impluse = body.Force * dt; + // 重力 + if(body.UseGravity) + { + velocity += m_Gravity * deltaTime; + } + + // 受力(冲量) + Vector3 impluse = body.Force * deltaTime; Vector3 deltaV = impluse / body.Weight; velocity += deltaV; - body.Velocity = velocity; - - position += velocity * dt; - - body.transform.position = position; if (prim.IsOnGround) - { - // pos=0, Vy=0 - position.y = 0.1f; - body.transform.position = position; - + { // 地面摩擦力 - if(body.Velocity.x != 0 && body.GroundFriction != 0) + if (body.Velocity.x != 0 && body.GroundFriction != 0) { - float dv = body.GroundFriction * dt; + float dv = body.GroundFriction * deltaTime; dv = Mathf.Min(dv, Mathf.Abs(body.Velocity.x)); dv = body.Velocity.x > 0 ? -dv : dv; velocity.x += dv; } - velocity.y = 0; - body.Velocity = velocity; } - else if(prim.IsInAir) // 空气摩擦力 + + if (prim.IsInAir) { + // 空气阻力 if(body.Velocity.x != 0 && body.AirFriction != 0) { - float dv = body.AirFriction * dt; + float dv = body.AirFriction * deltaTime; dv = Mathf.Min(dv, Mathf.Abs(body.Velocity.x)); dv = body.Velocity.x > 0 ? -dv : dv; velocity.x += dv; - body.Velocity = velocity; } } + position += velocity * deltaTime; + + body.Velocity = velocity; + body.transform.position = position; body.SetForce(Vector3.zero); } - - void SolveCollision(PhysicsPrimitive prim, PhysicsCollisionInfo collision, float dt) + + /// + /// 处理物体的环境(地面、墙体)约束 + /// + /// + /// + void HandleConstrain(PhysicsPrimitive prim, float deltaTime) + { + PhysicsBody body = prim.Body; + if (body == null) + return; + + Vector3 position = body.transform.position; + Vector3 velocity = body.Velocity; + + if (prim.IsOnGround) + { + position.y = PhysicsWorld.Ground; + velocity.y = 0; + } + + body.transform.position = position; + body.Velocity = velocity; + } + + void SolveCollision(PhysicsPrimitive prim, PhysicsCollisionInfo collision, float deltaTime) { PhysicsPrimitive other = collision.prim1 == prim ? collision.prim2 : collision.prim1; - if(prim.Body != null && other.Body != null) + + // 1. 对于刚体,根据碰撞对位置进行约束 + if(prim.Body != null) { Vector3 pos = prim.Body.transform.position; - pos.x += pos.x > collision.contact.x ? collision.size.x / 2f : - collision.size.x / 2f; + if(collision.size.x <= collision.size.y) + { + float offsetX = Mathf.Min(collision.size.x / 2f, 0.8f); + pos.x += prim.Position.x > collision.contact.x ? offsetX : -offsetX; + } + else + { + float offsetY = Mathf.Min(collision.size.y / 2f, 0.1f); + pos.y += prim.Position.y > collision.contact.y ? offsetY : -offsetY; + } prim.Body.transform.position = pos; } return; - - PhysicsBody body = prim.Body; - if (body == null) - return; - if (!body.UseGravity) - return; - Vector3 contact = collision.contact; - Vector3 dir = (prim.Position - contact).normalized; - dir.z = 0; - - float mag = Mathf.Max(0.3f, body.Velocity.magnitude); - - Vector3 position = body.transform.position; - position += mag * dir * dt; - body.Velocity = Vector3.zero; - body.transform.position = position; } // prim在当前帧是否有碰撞 diff --git a/Assets/Scripts/Props.meta b/Assets/Scripts/Props.meta new file mode 100644 index 00000000..bb96602e --- /dev/null +++ b/Assets/Scripts/Props.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f299520ed9fcf4a45858ad4ef5a8d5d1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Test/SaionjiUberAbility.cs b/Assets/Scripts/Test/SaionjiUberAbility.cs new file mode 100644 index 00000000..b4d6444f --- /dev/null +++ b/Assets/Scripts/Test/SaionjiUberAbility.cs @@ -0,0 +1,24 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class SaionjiUberAbility : UberAbility +{ + Avatar m_Avatar; + AbilitySystem m_AbilitySystem; + + public SaionjiUberAbility(Avatar avatar, AbilitySystem system) + { + m_Avatar = avatar; + m_AbilitySystem = system; + } + + public override void OnUpdate() + { + } + + public override void OnLateUpdate() + { + } + +} diff --git a/Assets/Scripts/Test/SaionjiUberAbility.cs.meta b/Assets/Scripts/Test/SaionjiUberAbility.cs.meta new file mode 100644 index 00000000..54511638 --- /dev/null +++ b/Assets/Scripts/Test/SaionjiUberAbility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 518687ee23ab1a8408e58ab11d3f5885 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: -- cgit v1.1-26-g67d0