mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
charactercontroller2k
This commit is contained in:
parent
0c98a51012
commit
1c46530f68
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2427a0fd987cc4d239b45820402d37f1
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 29d02e23dd78c434baee064aae1caed9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,56 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Controller2k
|
||||||
|
{
|
||||||
|
// Collision info used by the OpenCharacterController and sent to the OnOpenCharacterControllerHit message.
|
||||||
|
public struct CollisionInfo
|
||||||
|
{
|
||||||
|
// The collider that was hit by the controller.
|
||||||
|
public readonly Collider collider;
|
||||||
|
|
||||||
|
// The controller that hit the collider.
|
||||||
|
public readonly CharacterController2k controller;
|
||||||
|
|
||||||
|
// The game object that was hit by the controller.
|
||||||
|
public readonly GameObject gameObject;
|
||||||
|
|
||||||
|
// The direction the character Controller was moving in when the collision occured.
|
||||||
|
public readonly Vector3 moveDirection;
|
||||||
|
|
||||||
|
// How far the character has travelled until it hit the collider.
|
||||||
|
public readonly float moveLength;
|
||||||
|
|
||||||
|
// The normal of the surface we collided with in world space.
|
||||||
|
public readonly Vector3 normal;
|
||||||
|
|
||||||
|
// The impact point in world space.
|
||||||
|
public readonly Vector3 point;
|
||||||
|
|
||||||
|
// The rigidbody that was hit by the controller.
|
||||||
|
public readonly Rigidbody rigidbody;
|
||||||
|
|
||||||
|
// The transform that was hit by the controller.
|
||||||
|
public readonly Transform transform;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
// openCharacterController: The character controller that hit.
|
||||||
|
// hitInfo: The hit info.
|
||||||
|
// directionMoved: Direction moved when collision occured.
|
||||||
|
// distanceMoved: How far the character has travelled until it hit the collider.
|
||||||
|
public CollisionInfo(CharacterController2k openCharacterController,
|
||||||
|
RaycastHit hitInfo,
|
||||||
|
Vector3 directionMoved,
|
||||||
|
float distanceMoved)
|
||||||
|
{
|
||||||
|
collider = hitInfo.collider;
|
||||||
|
controller = openCharacterController;
|
||||||
|
gameObject = hitInfo.collider.gameObject;
|
||||||
|
moveDirection = directionMoved;
|
||||||
|
moveLength = distanceMoved;
|
||||||
|
normal = hitInfo.normal;
|
||||||
|
point = hitInfo.point;
|
||||||
|
rigidbody = hitInfo.rigidbody;
|
||||||
|
transform = hitInfo.transform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2bce0b825e3445f3b49647a68f0f85ab
|
||||||
|
timeCreated: 1584448919
|
26
Assets/Mirror/Examples/_Common/CharacterController2k/Extensions.cs
Executable file
26
Assets/Mirror/Examples/_Common/CharacterController2k/Extensions.cs
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
// CharacterController2k is based on Unity's OpenCharacterController, modified by vis2k, all rights reserved.
|
||||||
|
//
|
||||||
|
// -------------------------------------------------------------------------------------------------------------
|
||||||
|
// Original License from: https://github.com/Unity-Technologies/Standard-Assets-Characters:
|
||||||
|
// Licensed under the Unity Companion License for Unity-dependent projects--see Unity Companion License.
|
||||||
|
// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions.
|
||||||
|
//
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Controller2k
|
||||||
|
{
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
// Is floatA equal to zero? Takes floating point inaccuracy into account, by using Epsilon.
|
||||||
|
public static bool IsEqualToZero(this float floatA)
|
||||||
|
{
|
||||||
|
return Mathf.Abs(floatA) < Mathf.Epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is floatA not equal to zero? Takes floating point inaccuracy into account, by using Epsilon.
|
||||||
|
public static bool NotEqualToZero(this float floatA)
|
||||||
|
{
|
||||||
|
return Mathf.Abs(floatA) > Mathf.Epsilon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 60075d32bcb8144eb8ac8b9a5f0964fe
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,55 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Controller2k
|
||||||
|
{
|
||||||
|
public static class Helpers
|
||||||
|
{
|
||||||
|
// Get the top sphere's world position.
|
||||||
|
public static Vector3 GetTopSphereWorldPosition(Vector3 position, Vector3 transformedCenter, float scaledRadius, float scaledHeight)
|
||||||
|
{
|
||||||
|
Vector3 sphereOffsetY = Vector3.up * (scaledHeight / 2.0f - scaledRadius);
|
||||||
|
return position + transformedCenter + sphereOffsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// added to simulate collision checks for CanSetHeight/Center
|
||||||
|
// TODO can probably get rid of it and use the above function with proper parameters
|
||||||
|
public static Vector3 GetTopSphereWorldPositionSimulated(Transform transform, Vector3 center, float scaledRadius, float height)
|
||||||
|
{
|
||||||
|
float scaledHeight = height * transform.lossyScale.y;
|
||||||
|
Vector3 transformedCenter = transform.TransformVector(center);
|
||||||
|
return GetTopSphereWorldPosition(transform.position, transformedCenter, scaledRadius, scaledHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the bottom sphere's world position.
|
||||||
|
public static Vector3 GetBottomSphereWorldPosition(Vector3 position, Vector3 transformedCenter, float scaledRadius, float scaledHeight)
|
||||||
|
{
|
||||||
|
Vector3 sphereOffsetY = Vector3.up * (scaledHeight / 2.0f - scaledRadius);
|
||||||
|
return position + transformedCenter - sphereOffsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// added to simulate collision checks for CanSetHeight/Center
|
||||||
|
// TODO can probably get rid of it and use the above function with proper parameters
|
||||||
|
public static Vector3 GetBottomSphereWorldPositionSimulated(Transform transform, Vector3 center, float scaledRadius, float height)
|
||||||
|
{
|
||||||
|
float scaledHeight = height * transform.lossyScale.y;
|
||||||
|
Vector3 transformedCenter = transform.TransformVector(center);
|
||||||
|
return GetBottomSphereWorldPosition(transform.position, transformedCenter, scaledRadius, scaledHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate a new center if the height changes and preserve the foot position.
|
||||||
|
public static Vector3 CalculateCenterWithSameFootPosition(Vector3 center, float height, float newHeight, float skinWidth)
|
||||||
|
{
|
||||||
|
float localFootY = center.y - (height / 2.0f + skinWidth);
|
||||||
|
float newCenterY = localFootY + (newHeight / 2.0f + skinWidth);
|
||||||
|
return new Vector3(center.x, newCenterY, center.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the movement vector almost zero (i.e. very small)?
|
||||||
|
public static bool IsMoveVectorAlmostZero(Vector3 moveVector, float smallThreshold)
|
||||||
|
{
|
||||||
|
return Mathf.Abs(moveVector.x) <= smallThreshold &&
|
||||||
|
Mathf.Abs(moveVector.y) <= smallThreshold &&
|
||||||
|
Mathf.Abs(moveVector.z) <= smallThreshold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5f775b01ec9694dd48d4f0fb917bae6a
|
||||||
|
timeCreated: 1584448919
|
@ -0,0 +1,24 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Controller2k
|
||||||
|
{
|
||||||
|
// A vector used by the OpenCharacterController.
|
||||||
|
public struct MoveVector
|
||||||
|
{
|
||||||
|
// The move vector.
|
||||||
|
// Note: This gets used up during the move loop, so will be zero by the end of the loop.
|
||||||
|
public Vector3 moveVector;
|
||||||
|
|
||||||
|
// Can the movement slide along obstacles?
|
||||||
|
public bool canSlide;
|
||||||
|
|
||||||
|
// Constructor.
|
||||||
|
// newMoveVector: The move vector.
|
||||||
|
// newCanSlide: Can the movement slide along obstacles?
|
||||||
|
public MoveVector(Vector3 newMoveVector, bool newCanSlide = true)
|
||||||
|
{
|
||||||
|
moveVector = newMoveVector;
|
||||||
|
canSlide = newCanSlide;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f2e60d0f4bf94ed5a2dc010f693c75e6
|
||||||
|
timeCreated: 1584449049
|
@ -0,0 +1,97 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Controller2k
|
||||||
|
{
|
||||||
|
// Stuck info and logic used by the OpenCharacterController.
|
||||||
|
public class StuckInfo
|
||||||
|
{
|
||||||
|
// For keeping track of the character's position, to determine when the character gets stuck.
|
||||||
|
Vector3? stuckPosition;
|
||||||
|
|
||||||
|
// Count how long the character is in the same position.
|
||||||
|
int stuckPositionCount;
|
||||||
|
|
||||||
|
// If character's position does not change by more than this amount then we assume the character is stuck.
|
||||||
|
const float k_StuckDistance = 0.001f;
|
||||||
|
|
||||||
|
// If character collided this number of times during the movement loop then test if character is stuck by examining the position
|
||||||
|
const int k_HitCountForStuck = 6;
|
||||||
|
|
||||||
|
// Assume character is stuck if the position is the same for longer than this number of loop iterations
|
||||||
|
const int k_MaxStuckPositionCount = 1;
|
||||||
|
|
||||||
|
// Is the character stuck in the current move loop iteration?
|
||||||
|
public bool isStuck;
|
||||||
|
|
||||||
|
// Count the number of collisions during movement, to determine when the character gets stuck.
|
||||||
|
public int hitCount;
|
||||||
|
|
||||||
|
// Called when the move loop starts.
|
||||||
|
public void OnMoveLoop()
|
||||||
|
{
|
||||||
|
hitCount = 0;
|
||||||
|
stuckPositionCount = 0;
|
||||||
|
stuckPosition = null;
|
||||||
|
isStuck = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the character stuck during the movement loop (e.g. bouncing between 2 or more colliders)?
|
||||||
|
// characterPosition: The character's position.
|
||||||
|
// currentMoveVector: Current move vector.
|
||||||
|
// originalMoveVector: Original move vector.
|
||||||
|
public bool UpdateStuck(Vector3 characterPosition, Vector3 currentMoveVector,
|
||||||
|
Vector3 originalMoveVector)
|
||||||
|
{
|
||||||
|
// First test
|
||||||
|
if (!isStuck)
|
||||||
|
{
|
||||||
|
// From Quake2: "if velocity is against the original velocity, stop dead to avoid tiny occilations in sloping corners"
|
||||||
|
if (currentMoveVector.sqrMagnitude.NotEqualToZero() &&
|
||||||
|
Vector3.Dot(currentMoveVector, originalMoveVector) <= 0.0f)
|
||||||
|
{
|
||||||
|
isStuck = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second test
|
||||||
|
if (!isStuck)
|
||||||
|
{
|
||||||
|
// Test if collided and while position remains the same
|
||||||
|
if (hitCount < k_HitCountForStuck)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stuckPosition == null)
|
||||||
|
{
|
||||||
|
stuckPosition = characterPosition;
|
||||||
|
}
|
||||||
|
else if (Vector3.Distance(stuckPosition.Value, characterPosition) <= k_StuckDistance)
|
||||||
|
{
|
||||||
|
stuckPositionCount++;
|
||||||
|
if (stuckPositionCount > k_MaxStuckPositionCount)
|
||||||
|
{
|
||||||
|
isStuck = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stuckPositionCount = 0;
|
||||||
|
stuckPosition = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStuck)
|
||||||
|
{
|
||||||
|
isStuck = false;
|
||||||
|
hitCount = 0;
|
||||||
|
stuckPositionCount = 0;
|
||||||
|
stuckPosition = null;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fed936502da948c4b94c434014c8852f
|
||||||
|
timeCreated: 1584449202
|
Loading…
Reference in New Issue
Block a user