Add files via upload

This commit is contained in:
Olezen
2019-07-15 20:10:07 +02:00
committed by GitHub
parent 821c4fb2f2
commit 8395b0921e
33 changed files with 2298 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraWaterCheck : MonoBehaviour {
private List<Collider> triggers = new List<Collider> ();
private void OnTriggerEnter (Collider other) {
if (!triggers.Contains (other))
triggers.Add (other);
}
private void OnTriggerExit (Collider other) {
if (triggers.Contains (other))
triggers.Remove (other);
}
public bool IsUnderwater () {
foreach (Collider trigger in triggers) {
if (trigger.GetComponentInParent<Water> ())
return true;
}
return false;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6f1d7457460534f489c8262e748c0dfc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,227 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &5467285083954485886
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5467285083954485881}
- component: {fileID: 5467285083954485883}
- component: {fileID: 5467285083954485880}
m_Layer: 8
m_Name: Camera
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &5467285083954485881
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5467285083954485886}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 5467285085316221433}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!20 &5467285083954485883
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5467285083954485886}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.01
far clip plane: 1000
field of view: 90
orthographic: 0
orthographic size: 5
m_Depth: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!81 &5467285083954485880
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5467285083954485886}
m_Enabled: 1
--- !u!1 &5467285084242854813
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5467285084242854812}
- component: {fileID: 5467285084242854815}
m_Layer: 8
m_Name: Example player prefab
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &5467285084242854812
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5467285084242854813}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 5467285085316221433}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &5467285084242854815
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5467285084242854813}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 601d4686cc0b70d45a98271d52094850, type: 3}
m_Name:
m_EditorClassIdentifier:
colliderSize: {x: 1, y: 2, z: 1}
collisionType: 1
weight: 75
rigidbodyPushForce: 0.5
solidCollider: 1
viewTransform: {fileID: 5467285085316221433}
playerRotationTransform: {fileID: 5467285084242854812}
crouchingHeightMultiplier: 0.5
crouchingSpeed: 10
crouchingEnabled: 1
slidingEnabled: 0
movementConfig:
autoBhop: 1
gravity: 20
jumpForce: 6.5
friction: 6
maxSpeed: 6
maxVelocity: 50
slopeLimit: 45
clampAirSpeed: 1
airCap: 0.4
airAcceleration: 12
airFriction: 0.4
walkSpeed: 7
sprintSpeed: 12
acceleration: 14
deceleration: 10
crouchSpeed: 4
crouchAcceleration: 8
crouchDeceleration: 4
crouchFriction: 3
minimumSlideSpeed: 9
maximumSlideSpeed: 18
slideSpeedMultiplier: 1.75
slideFriction: 15
downhillSlideSpeedMultiplier: 3
slideDelay: 1
swimUpSpeed: 12
underwaterSwimSpeed: 3
underwaterAcceleration: 6
underwaterDeceleration: 3
underwaterFriction: 2
underwaterGravity: 6
underwaterVelocityDampening: 2
--- !u!1 &5467285085316221438
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5467285085316221433}
- component: {fileID: 5467285085316221432}
m_Layer: 8
m_Name: Camera holder
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &5467285085316221433
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5467285085316221438}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 5467285083954485881}
m_Father: {fileID: 5467285084242854812}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &5467285085316221432
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5467285085316221438}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 604093a680e6d5a488206647cc35be23, type: 3}
m_Name:
m_EditorClassIdentifier:
bodyTransform: {fileID: 5467285084242854812}
sensitivityMultiplier: 1
horizontalSensitivity: 1
verticalSensitivity: 1
minYRotation: -90
maxYRotation: 90
bodyRotation: 0
cameraRotation: {x: 0, y: 0, z: 0}
leanInput: 0
sway: 0

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a840589249729984398df665ca6e2508
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d28ade60e8ecfdf42970424f92cd001e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,27 @@

public static class IntExtensions {
/// <summary>
///
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static bool HasFlag (this int a, int b) { return (a & b) == b; }
/// <summary>
///
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static int AddFlag (this int a, int b) { return a |= b; }
/// <summary>
///
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static int RemoveFlag (this int a, int b) { return a &= ~b; }
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: dcb5a3ee06e4bc947a5486cd6b06e1ac
timeCreated: 1522007229
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
using UnityEngine;
public static class VectorExtensions {
public static Vector3 VectorMa (Vector3 start, float scale, Vector3 direction) {
var dest = new Vector3 (
start.x + direction.x * scale,
start.y + direction.y * scale,
start.z + direction.z * scale
);
return dest;
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 390f54ee3fdd73a46916bef3d176880f
timeCreated: 1522007209
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3b1e33b474eb4614aa6a5972cd4febbc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
using UnityEngine;
namespace Fragsurf.Movement {
public interface ISurfControllable {
MoveType moveType { get; }
MoveData moveData { get; }
Collider collider { get; }
GameObject groundObject { get; set; }
Vector3 forward { get; }
Vector3 right { get; }
Vector3 up { get; }
Vector3 baseVelocity { get; }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ce6dfe3283d91574aa798e5855fc14dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@

namespace Fragsurf.Movement {
[System.Flags]
public enum InputButtons {
None = 0,
Jump = 1 << 1,
Duck = 1 << 2,
Speed = 1 << 3,
MoveLeft = 1 << 4,
MoveRight = 1 << 5,
MoveForward = 1 << 6,
MoveBack = 1 << 7
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a3ecfdc05e51544ead319fa03e199fe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using UnityEngine;
namespace Fragsurf.Movement {
public enum MoveType {
None,
Walk,
Noclip, // not implemented
Ladder, // not implemented
}
public class MoveData {
///// Fields /////
public Transform playerTransform;
public Transform viewTransform;
public Vector3 viewTransformDefaultLocalPos;
public Vector3 origin;
public Vector3 viewAngles;
public Vector3 velocity;
public float forwardMove;
public float sideMove;
public float upMove;
public float surfaceFriction = 1f;
public float gravityFactor = 1f;
public float walkFactor = 1f;
public float verticalAxis = 0f;
public float horizontalAxis = 0f;
public bool wishJump = false;
public bool crouching = false;
public bool sprinting = false;
public float rigidbodyPushForce = 1f;
public float defaultHeight = 2f;
public float crouchingHeight = 1f;
public float crouchingSpeed = 10f;
public bool toggleCrouch = false;
public bool slidingEnabled = false;
public bool underwater = false;
public bool cameraUnderwater = false;
public bool grounded = false;
public bool groundedTemp = false;
public float fallingVelocity = 0f;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01040416c3a2d664aacf1cdfc7a46675
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
using UnityEngine;
namespace Fragsurf.Movement {
[System.Serializable]
public class MovementConfig {
[Header ("Jumping and gravity")]
public bool autoBhop = true;
public float gravity = 20f;
public float jumpForce = 6.5f;
[Header ("General physics")]
public float friction = 6f;
public float maxSpeed = 6f;
public float maxVelocity = 50f;
[Range (30f, 75f)] public float slopeLimit = 45f;
[Header ("Air movement")]
public bool clampAirSpeed = true;
public float airCap = 0.4f;
public float airAcceleration = 12f;
public float airFriction = 0.4f;
[Header ("Ground movement")]
public float walkSpeed = 7f;
public float sprintSpeed = 12f;
public float acceleration = 14f;
public float deceleration = 10f;
[Header ("Crouch movement")]
public float crouchSpeed = 4f;
public float crouchAcceleration = 8f;
public float crouchDeceleration = 4f;
public float crouchFriction = 3f;
[Header ("Sliding")]
public float minimumSlideSpeed = 9f;
public float maximumSlideSpeed = 18f;
public float slideSpeedMultiplier = 1.75f;
public float slideFriction = 14f;
public float downhillSlideSpeedMultiplier = 2.5f;
public float slideDelay = 0.5f;
[Header ("Underwater")]
public float swimUpSpeed = 12f;
public float underwaterSwimSpeed = 3f;
public float underwaterAcceleration = 6f;
public float underwaterDeceleration = 3f;
public float underwaterFriction = 2f;
public float underwaterGravity = 6f;
public float underwaterVelocityDampening = 2f;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3a624624f32edf641ba5049808071214
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,366 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace Fragsurf.Movement {
/// <summary>
/// Easily add a surfable character to the scene
/// </summary>
[AddComponentMenu ("Fragsurf/Surf Character")]
public class SurfCharacter : MonoBehaviour, ISurfControllable {
public enum ColliderType {
Capsule,
Box
}
///// Fields /////
[Header("Physics Settings")]
public Vector3 colliderSize = new Vector3 (1f, 2f, 1f);
public ColliderType collisionType;
public float weight = 75f;
public float rigidbodyPushForce = 2f;
public bool solidCollider = false;
[Header("View Settings")]
public Transform viewTransform;
public Transform playerRotationTransform;
[Header ("Crouching setup")]
public float crouchingHeightMultiplier = 0.5f;
public float crouchingSpeed = 10f;
float defaultHeight;
bool allowCrouch = true; // This is separate because you shouldn't be able to toggle crouching on and off during gameplay for various reasons
[Header ("Features")]
public bool crouchingEnabled = true;
public bool slidingEnabled = false;
[Header ("Movement Config")]
[SerializeField]
public MovementConfig movementConfig;
private GameObject _groundObject;
private Vector3 _baseVelocity;
private Collider _collider;
private Vector3 _angles;
private Vector3 _startPosition;
private GameObject _colliderObject;
private GameObject _cameraWaterCheckObject;
private CameraWaterCheck _cameraWaterCheck;
private MoveData _moveData = new MoveData ();
private SurfController _controller = new SurfController ();
private Rigidbody rb;
private List<Collider> triggers = new List<Collider> ();
private int numberOfTriggers = 0;
private bool underwater = false;
///// Properties /////
public MoveType moveType { get { return MoveType.Walk; } }
public MovementConfig moveConfig { get { return movementConfig; } }
public MoveData moveData { get { return _moveData; } }
public new Collider collider { get { return _collider; } }
public GameObject groundObject {
get { return _groundObject; }
set { _groundObject = value; }
}
public Vector3 baseVelocity { get { return _baseVelocity; } }
public Vector3 forward { get { return viewTransform.forward; } }
public Vector3 right { get { return viewTransform.right; } }
public Vector3 up { get { return viewTransform.up; } }
Vector3 prevPosition;
///// Methods /////
private void Awake () {
_controller.playerTransform = playerRotationTransform;
if (viewTransform != null) {
_controller.camera = viewTransform;
_controller.cameraYPos = viewTransform.localPosition.y;
}
}
private void Start () {
_colliderObject = new GameObject ("PlayerCollider");
_colliderObject.layer = gameObject.layer;
_colliderObject.transform.SetParent (transform);
_colliderObject.transform.rotation = Quaternion.identity;
_colliderObject.transform.localPosition = Vector3.zero;
_colliderObject.transform.SetSiblingIndex (0);
// Water check
_cameraWaterCheckObject = new GameObject ("Camera water check");
_cameraWaterCheckObject.layer = gameObject.layer;
_cameraWaterCheckObject.transform.position = viewTransform.position;
SphereCollider _cameraWaterCheckSphere = _cameraWaterCheckObject.AddComponent<SphereCollider> ();
_cameraWaterCheckSphere.radius = 0.1f;
_cameraWaterCheckSphere.isTrigger = true;
Rigidbody _cameraWaterCheckRb = _cameraWaterCheckObject.AddComponent<Rigidbody> ();
_cameraWaterCheckRb.useGravity = false;
_cameraWaterCheckRb.isKinematic = true;
_cameraWaterCheck = _cameraWaterCheckObject.AddComponent<CameraWaterCheck> ();
prevPosition = transform.position;
if (viewTransform == null)
viewTransform = Camera.main.transform;
if (playerRotationTransform == null && transform.childCount > 0)
playerRotationTransform = transform.GetChild (0);
_collider = gameObject.GetComponent<Collider> ();
if (_collider != null)
GameObject.Destroy (_collider);
// rigidbody is required to collide with triggers
rb = gameObject.GetComponent<Rigidbody> ();
if (rb == null)
rb = gameObject.AddComponent<Rigidbody> ();
allowCrouch = crouchingEnabled;
rb.isKinematic = true;
rb.useGravity = false;
rb.angularDrag = 0f;
rb.drag = 0f;
rb.mass = weight;
switch (collisionType) {
// Box collider
case ColliderType.Box:
_collider = _colliderObject.AddComponent<BoxCollider> ();
var boxc = (BoxCollider)_collider;
boxc.size = colliderSize;
defaultHeight = boxc.size.y;
break;
// Capsule collider
case ColliderType.Capsule:
_collider = _colliderObject.AddComponent<CapsuleCollider> ();
var capc = (CapsuleCollider)_collider;
capc.height = colliderSize.y;
capc.radius = colliderSize.x / 2f;
defaultHeight = capc.height;
break;
}
_moveData.rigidbodyPushForce = rigidbodyPushForce;
_moveData.slidingEnabled = slidingEnabled;
_moveData.playerTransform = transform;
_moveData.viewTransform = viewTransform;
_moveData.viewTransformDefaultLocalPos = viewTransform.localPosition;
_moveData.defaultHeight = defaultHeight;
_moveData.crouchingHeight = crouchingHeightMultiplier;
_moveData.crouchingSpeed = crouchingSpeed;
_collider.isTrigger = !solidCollider;
_moveData.origin = transform.position;
_startPosition = transform.position;
}
private void Update () {
_colliderObject.transform.rotation = Quaternion.identity;
//UpdateTestBinds ();
UpdateMoveData ();
// Previous movement code
Vector3 positionalMovement = transform.position - prevPosition;
transform.position = prevPosition;
moveData.origin += positionalMovement;
// Triggers
if (numberOfTriggers != triggers.Count) {
numberOfTriggers = triggers.Count;
underwater = false;
triggers.RemoveAll (item => item == null);
foreach (Collider trigger in triggers) {
if (trigger == null)
continue;
if (trigger.GetComponentInParent<Water> ())
underwater = true;
}
}
_moveData.cameraUnderwater = _cameraWaterCheck.IsUnderwater ();
_cameraWaterCheckObject.transform.position = viewTransform.position;
moveData.underwater = underwater;
if (allowCrouch)
_controller.Crouch (this, movementConfig, Time.deltaTime);
_controller.ProcessMovement (this, movementConfig, Time.deltaTime);
transform.position = moveData.origin;
prevPosition = transform.position;
_colliderObject.transform.rotation = Quaternion.identity;
}
private void UpdateTestBinds () {
if (Input.GetKeyDown (KeyCode.Backspace))
ResetPosition ();
}
private void ResetPosition () {
moveData.velocity = Vector3.zero;
moveData.origin = _startPosition;
}
private void UpdateMoveData () {
_moveData.verticalAxis = Input.GetAxisRaw ("Vertical");
_moveData.horizontalAxis = Input.GetAxisRaw ("Horizontal");
_moveData.sprinting = Input.GetButton ("Sprint");
if (Input.GetButtonDown ("Crouch"))
_moveData.crouching = true;
if (!Input.GetButton ("Crouch"))
_moveData.crouching = false;
bool moveLeft = _moveData.horizontalAxis < 0f;
bool moveRight = _moveData.horizontalAxis > 0f;
bool moveFwd = _moveData.verticalAxis > 0f;
bool moveBack = _moveData.verticalAxis < 0f;
bool jump = Input.GetButton ("Jump");
if (!moveLeft && !moveRight)
_moveData.sideMove = 0f;
else if (moveLeft)
_moveData.sideMove = -moveConfig.acceleration;
else if (moveRight)
_moveData.sideMove = moveConfig.acceleration;
if (!moveFwd && !moveBack)
_moveData.forwardMove = 0f;
else if (moveFwd)
_moveData.forwardMove = moveConfig.acceleration;
else if (moveBack)
_moveData.forwardMove = -moveConfig.acceleration;
if (Input.GetButtonDown ("Jump"))
_moveData.wishJump = true;
if (!Input.GetButton ("Jump"))
_moveData.wishJump = false;
_moveData.viewAngles = _angles;
}
private void DisableInput () {
_moveData.verticalAxis = 0f;
_moveData.horizontalAxis = 0f;
_moveData.sideMove = 0f;
_moveData.forwardMove = 0f;
_moveData.wishJump = false;
}
/// <summary>
///
/// </summary>
/// <param name="angle"></param>
/// <param name="from"></param>
/// <param name="to"></param>
/// <returns></returns>
public static float ClampAngle (float angle, float from, float to) {
if (angle < 0f)
angle = 360 + angle;
if (angle > 180f)
return Mathf.Max (angle, 360 + from);
return Mathf.Min (angle, to);
}
private void OnTriggerEnter (Collider other) {
if (!triggers.Contains (other))
triggers.Add (other);
}
private void OnTriggerExit (Collider other) {
if (triggers.Contains (other))
triggers.Remove (other);
}
private void OnCollisionStay (Collision collision) {
if (collision.rigidbody == null)
return;
Vector3 relativeVelocity = collision.relativeVelocity * collision.rigidbody.mass / 50f;
Vector3 impactVelocity = new Vector3 (relativeVelocity.x * 0.0025f, relativeVelocity.y * 0.00025f, relativeVelocity.z * 0.0025f);
float maxYVel = Mathf.Max (moveData.velocity.y, 10f);
Vector3 newVelocity = new Vector3 (moveData.velocity.x + impactVelocity.x, Mathf.Clamp (moveData.velocity.y + Mathf.Clamp (impactVelocity.y, -0.5f, 0.5f), -maxYVel, maxYVel), moveData.velocity.z + impactVelocity.z);
newVelocity = Vector3.ClampMagnitude (newVelocity, Mathf.Max (moveData.velocity.magnitude, 30f));
moveData.velocity = newVelocity;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 601d4686cc0b70d45a98271d52094850
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,651 @@
using UnityEngine;
using Fragsurf.TraceUtil;
namespace Fragsurf.Movement {
public class SurfController {
///// Fields /////
[HideInInspector] public Transform playerTransform;
private ISurfControllable _surfer;
private MovementConfig _config;
private float _deltaTime;
public bool jumping = false;
public bool crouching = false;
public float speed = 0f;
public Transform camera;
public float cameraYPos = 0f;
private float slideSpeedCurrent = 0f;
private Vector3 slideDirection = Vector3.forward;
private bool sliding = false;
private bool wasSliding = false;
private float slideDelay = 0f;
private bool uncrouchDown = false;
private float crouchLerp = 0f;
private float frictionMult = 1f;
///// Methods /////
Vector3 groundNormal = Vector3.up;
/// <summary>
///
/// </summary>
public void ProcessMovement (ISurfControllable surfer, MovementConfig config, float deltaTime) {
// cache instead of passing around parameters
_surfer = surfer;
_config = config;
_deltaTime = deltaTime;
if (!_surfer.moveData.underwater) {
if (_surfer.moveData.velocity.y <= 0f)
jumping = false;
// apply gravity
if (_surfer.groundObject == null) {
_surfer.moveData.velocity.y -= (_surfer.moveData.gravityFactor * _config.gravity * _deltaTime);
_surfer.moveData.velocity.y += _surfer.baseVelocity.y * _deltaTime;
}
// input velocity, check for ground
CheckGrounded ();
CalculateMovementVelocity ();
} else {
// Do underwater logic
UnderwaterPhysics ();
}
float yVel = _surfer.moveData.velocity.y;
_surfer.moveData.velocity.y = 0f;
_surfer.moveData.velocity = Vector3.ClampMagnitude (_surfer.moveData.velocity, _config.maxVelocity);
speed = _surfer.moveData.velocity.magnitude;
_surfer.moveData.velocity.y = yVel;
float maxDistPerFrame = 1f;
Vector3 velocityThisFrame = _surfer.moveData.velocity * _deltaTime;
float velocityDistLeft = velocityThisFrame.magnitude;
float initialVel = velocityDistLeft;
while (velocityDistLeft > 0f) {
float amountThisLoop = Mathf.Min (maxDistPerFrame, velocityDistLeft);
velocityDistLeft -= amountThisLoop;
// increment origin
Vector3 velThisLoop = velocityThisFrame * (amountThisLoop / initialVel);
_surfer.moveData.origin += velThisLoop;
// don't penetrate walls
SurfPhysics.ResolveCollisions (_surfer.collider, ref _surfer.moveData.origin, ref _surfer.moveData.velocity, _surfer.moveData.rigidbodyPushForce);
}
_surfer.moveData.groundedTemp = _surfer.moveData.grounded;
_surfer = null;
}
/// <summary>
///
/// </summary>
private void CalculateMovementVelocity () {
switch (_surfer.moveType) {
case MoveType.Walk:
if (_surfer.groundObject == null) {
/*
// AIR MOVEMENT
*/
wasSliding = false;
// apply movement from input
_surfer.moveData.velocity += AirInputMovement ();
// let the magic happen
SurfPhysics.Reflect (ref _surfer.moveData.velocity, _surfer.collider, _surfer.moveData.origin, _deltaTime);
} else {
/*
// GROUND MOVEMENT
*/
// Sliding
if (!wasSliding) {
slideDirection = new Vector3 (_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z).normalized;
slideSpeedCurrent = Mathf.Max (_config.maximumSlideSpeed, new Vector3 (_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z).magnitude);
}
sliding = false;
if (_surfer.moveData.velocity.magnitude > _config.minimumSlideSpeed && _surfer.moveData.slidingEnabled && _surfer.moveData.crouching && slideDelay <= 0f) {
if (!wasSliding)
slideSpeedCurrent = Mathf.Clamp (slideSpeedCurrent * _config.slideSpeedMultiplier, _config.minimumSlideSpeed, _config.maximumSlideSpeed);
sliding = true;
wasSliding = true;
SlideMovement ();
return;
} else {
if (slideDelay > 0f)
slideDelay -= _deltaTime;
if (wasSliding)
slideDelay = _config.slideDelay;
wasSliding = false;
}
float fric = crouching ? _config.crouchFriction : _config.friction;
float accel = crouching ? _config.crouchAcceleration : _config.acceleration;
float decel = crouching ? _config.crouchDeceleration : _config.deceleration;
// Get movement directions
Vector3 forward = Vector3.Cross (groundNormal, -playerTransform.right);
Vector3 right = Vector3.Cross (groundNormal, forward);
float speed = _surfer.moveData.sprinting ? _config.sprintSpeed : _config.walkSpeed;
if (crouching)
speed = _config.crouchSpeed;
Vector3 _wishDir;
// Jump and friction
if (_surfer.moveData.wishJump) {
ApplyFriction (0.0f, true, true);
Jump ();
return;
} else {
ApplyFriction (1.0f * frictionMult, true, true);
}
float forwardMove = _surfer.moveData.verticalAxis;
float rightMove = _surfer.moveData.horizontalAxis;
_wishDir = forwardMove * forward + rightMove * right;
_wishDir.Normalize ();
Vector3 moveDirNorm = _wishDir;
Vector3 forwardVelocity = Vector3.Cross (groundNormal, Quaternion.AngleAxis (-90, Vector3.up) * new Vector3 (_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z));
// Set the target speed of the player
float _wishSpeed = _wishDir.magnitude;
_wishSpeed *= speed;
// Accelerate
float yVel = _surfer.moveData.velocity.y;
Accelerate (_wishDir, _wishSpeed, accel * Mathf.Min (frictionMult, 1f), false);
float maxVelocityMagnitude = _config.maxVelocity;
_surfer.moveData.velocity = Vector3.ClampMagnitude (new Vector3 (_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z), maxVelocityMagnitude);
_surfer.moveData.velocity.y = yVel;
// Calculate how much slopes should affect movement
float yVelocityNew = forwardVelocity.normalized.y * new Vector3 (_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z).magnitude;
// Apply the Y-movement from slopes
_surfer.moveData.velocity.y = yVelocityNew * (_wishDir.y < 0f ? 1.2f : 1.0f);
float removableYVelocity = _surfer.moveData.velocity.y - yVelocityNew;
}
break;
} // END OF SWITCH STATEMENT
}
private void UnderwaterPhysics () {
_surfer.moveData.velocity = Vector3.Lerp (_surfer.moveData.velocity, Vector3.zero, _config.underwaterVelocityDampening * _deltaTime);
// Gravity
if (!CheckGrounded ())
_surfer.moveData.velocity.y -= _config.underwaterGravity * _deltaTime;
// Swimming upwards
if (Input.GetButton ("Jump"))
_surfer.moveData.velocity.y += _config.swimUpSpeed * _deltaTime;
float fric = _config.underwaterFriction;
float accel = _config.underwaterAcceleration;
float decel = _config.underwaterDeceleration;
ApplyFriction (1f, true, false);
// Get movement directions
Vector3 forward = Vector3.Cross (groundNormal, -playerTransform.right);
Vector3 right = Vector3.Cross (groundNormal, forward);
float speed = _config.underwaterSwimSpeed;
Vector3 _wishDir;
float forwardMove = _surfer.moveData.verticalAxis;
float rightMove = _surfer.moveData.horizontalAxis;
_wishDir = forwardMove * forward + rightMove * right;
_wishDir.Normalize ();
Vector3 moveDirNorm = _wishDir;
Vector3 forwardVelocity = Vector3.Cross (groundNormal, Quaternion.AngleAxis (-90, Vector3.up) * new Vector3 (_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z));
// Set the target speed of the player
float _wishSpeed = _wishDir.magnitude;
_wishSpeed *= speed;
// Accelerate
float yVel = _surfer.moveData.velocity.y;
Accelerate (_wishDir, _wishSpeed, accel, false);
float maxVelocityMagnitude = _config.maxVelocity;
_surfer.moveData.velocity = Vector3.ClampMagnitude (new Vector3 (_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z), maxVelocityMagnitude);
_surfer.moveData.velocity.y = yVel;
float yVelStored = _surfer.moveData.velocity.y;
_surfer.moveData.velocity.y = 0f;
// Calculate how much slopes should affect movement
float yVelocityNew = forwardVelocity.normalized.y * new Vector3 (_surfer.moveData.velocity.x, 0f, _surfer.moveData.velocity.z).magnitude;
// Apply the Y-movement from slopes
_surfer.moveData.velocity.y = Mathf.Min (Mathf.Max (0f, yVelocityNew) + yVelStored, speed);
// Jumping out of water
bool movingForwards = playerTransform.InverseTransformVector (_surfer.moveData.velocity).z > 0f;
Trace waterJumpTrace = TraceBounds (playerTransform.position, playerTransform.position + playerTransform.forward * 0.1f, SurfPhysics.groundLayerMask);
if (waterJumpTrace.hitCollider != null && Vector3.Angle (Vector3.up, waterJumpTrace.planeNormal) >= _config.slopeLimit && Input.GetButton ("Jump") && !_surfer.moveData.cameraUnderwater && movingForwards)
_surfer.moveData.velocity.y = Mathf.Max (_surfer.moveData.velocity.y, _config.jumpForce);
}
private void Accelerate (Vector3 wishDir, float wishSpeed, float acceleration, bool yMovement) {
// Initialise variables
float _addSpeed;
float _accelerationSpeed;
float _currentSpeed;
// again, no idea
_currentSpeed = Vector3.Dot (_surfer.moveData.velocity, wishDir);
_addSpeed = wishSpeed - _currentSpeed;
// If you're not actually increasing your speed, stop here.
if (_addSpeed <= 0)
return;
// won't bother trying to understand any of this, really
_accelerationSpeed = Mathf.Min (acceleration * _deltaTime * wishSpeed, _addSpeed);
// Add the velocity.
_surfer.moveData.velocity.x += _accelerationSpeed * wishDir.x;
if (yMovement) { _surfer.moveData.velocity.y += _accelerationSpeed * wishDir.y; }
_surfer.moveData.velocity.z += _accelerationSpeed * wishDir.z;
}
private void ApplyFriction (float t, bool yAffected, bool grounded) {
// Initialise variables
Vector3 _vel = _surfer.moveData.velocity;
float _speed;
float _newSpeed;
float _control;
float _drop;
// Set Y to 0, speed to the magnitude of movement and drop to 0. I think drop is the amount of speed that is lost, but I just stole this from the internet, idk.
_vel.y = 0.0f;
_speed = _vel.magnitude;
_drop = 0.0f;
float fric = crouching ? _config.crouchFriction : _config.friction;
float accel = crouching ? _config.crouchAcceleration : _config.acceleration;
float decel = crouching ? _config.crouchDeceleration : _config.deceleration;
// Only apply friction if the player is grounded
if (grounded) {
// i honestly have no idea what this does tbh
_vel.y = _surfer.moveData.velocity.y;
_control = _speed < decel ? decel : _speed;
_drop = _control * fric * _deltaTime * t;
}
// again, no idea, but comments look cool
_newSpeed = Mathf.Max (_speed - _drop, 0f);
if (_speed > 0.0f)
_newSpeed /= _speed;
// Set the end-velocity
_surfer.moveData.velocity.x *= _newSpeed;
if (yAffected == true) { _surfer.moveData.velocity.y *= _newSpeed; }
_surfer.moveData.velocity.z *= _newSpeed;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private Vector3 AirInputMovement () {
Vector3 wishVel, wishDir;
float wishSpeed;
GetWishValues (out wishVel, out wishDir, out wishSpeed);
if (_config.clampAirSpeed && (wishSpeed != 0f && (wishSpeed > _config.maxSpeed))) {
wishVel = wishVel * (_config.maxSpeed / wishSpeed);
wishSpeed = _config.maxSpeed;
}
return SurfPhysics.AirAccelerate (_surfer.moveData.velocity, wishDir, wishSpeed, _config.airAcceleration, _config.airCap, _deltaTime);
}
/// <summary>
///
/// </summary>
/// <param name="wishVel"></param>
/// <param name="wishDir"></param>
/// <param name="wishSpeed"></param>
private void GetWishValues (out Vector3 wishVel, out Vector3 wishDir, out float wishSpeed) {
wishVel = Vector3.zero;
wishDir = Vector3.zero;
wishSpeed = 0f;
Vector3 forward = _surfer.forward,
right = _surfer.right;
forward [1] = 0;
right [1] = 0;
forward.Normalize ();
right.Normalize ();
for (int i = 0; i < 3; i++)
wishVel [i] = forward [i] * _surfer.moveData.forwardMove + right [i] * _surfer.moveData.sideMove;
wishVel [1] = 0;
wishSpeed = wishVel.magnitude;
wishDir = wishVel.normalized;
}
/// <summary>
///
/// </summary>
/// <param name="velocity"></param>
/// <param name="jumpPower"></param>
private void Jump () {
if (!_config.autoBhop)
_surfer.moveData.wishJump = false;
_surfer.moveData.velocity.y += _config.jumpForce;
jumping = true;
}
/// <summary>
///
/// </summary>
private bool CheckGrounded () {
_surfer.moveData.surfaceFriction = 1f;
var movingUp = _surfer.moveData.velocity.y > 0f;
var trace = TraceToFloor ();
float groundSteepness = Vector3.Angle (Vector3.up, trace.planeNormal);
if (trace.hitCollider == null || groundSteepness > _config.slopeLimit || (jumping && _surfer.moveData.velocity.y > 0f)) {
SetGround (null);
if (movingUp && _surfer.moveType != MoveType.Noclip)
_surfer.moveData.surfaceFriction = _config.airFriction;
return false;
} else {
groundNormal = trace.planeNormal;
SetGround (trace.hitCollider.gameObject);
return true;
}
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
private void SetGround (GameObject obj) {
if (obj != null) {
_surfer.groundObject = obj;
_surfer.moveData.velocity.y = 0;
} else
_surfer.groundObject = null;
}
/// <summary>
///
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <param name="layerMask"></param>
/// <returns></returns>
private Trace TraceBounds (Vector3 start, Vector3 end, int layerMask) {
return Tracer.TraceCollider (_surfer.collider, start, end, layerMask);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private Trace TraceToFloor () {
var down = _surfer.moveData.origin;
down.y -= 0.1f;
return Tracer.TraceCollider (_surfer.collider, _surfer.moveData.origin, down, SurfPhysics.groundLayerMask);
}
public void Crouch (ISurfControllable surfer, MovementConfig config, float deltaTime) {
_surfer = surfer;
_config = config;
_deltaTime = deltaTime;
if (_surfer == null)
return;
if (_surfer.collider == null)
return;
bool grounded = _surfer.groundObject != null;
bool wantsToCrouch = _surfer.moveData.crouching;
float crouchingHeight = Mathf.Clamp (_surfer.moveData.crouchingHeight, 0.01f, 1f);
float heightDifference = _surfer.moveData.defaultHeight - _surfer.moveData.defaultHeight * crouchingHeight;
if (grounded)
uncrouchDown = false;
// Crouching input
if (grounded)
crouchLerp = Mathf.Lerp (crouchLerp, wantsToCrouch ? 1f : 0f, _deltaTime * _surfer.moveData.crouchingSpeed);
else if (!grounded && !wantsToCrouch && crouchLerp < 0.95f)
crouchLerp = 0f;
else if (!grounded && wantsToCrouch)
crouchLerp = 1f;
// Collider and position changing
if (crouchLerp > 0.9f && !crouching) {
// Begin crouching
crouching = true;
if (_surfer.collider.GetType () == typeof (BoxCollider)) {
// Box collider
BoxCollider boxCollider = (BoxCollider)_surfer.collider;
boxCollider.size = new Vector3 (boxCollider.size.x, _surfer.moveData.defaultHeight * crouchingHeight, boxCollider.size.z);
} else if (_surfer.collider.GetType () == typeof (CapsuleCollider)) {
// Capsule collider
CapsuleCollider capsuleCollider = (CapsuleCollider)_surfer.collider;
capsuleCollider.height = _surfer.moveData.defaultHeight * crouchingHeight;
}
// Move position and stuff
_surfer.moveData.origin += heightDifference / 2 * (grounded ? Vector3.down : Vector3.up);
foreach (Transform child in playerTransform) {
if (child == _surfer.moveData.viewTransform)
continue;
child.localPosition = new Vector3 (child.localPosition.x, child.localPosition.y * crouchingHeight, child.localPosition.z);
}
uncrouchDown = !grounded;
} else if (crouching) {
// Check if the player can uncrouch
bool canUncrouch = true;
if (_surfer.collider.GetType () == typeof (BoxCollider)) {
// Box collider
BoxCollider boxCollider = (BoxCollider)_surfer.collider;
Vector3 halfExtents = boxCollider.size * 0.5f;
Vector3 startPos = boxCollider.transform.position;
Vector3 endPos = boxCollider.transform.position + (uncrouchDown ? Vector3.down : Vector3.up) * heightDifference;
Trace trace = Tracer.TraceBox (startPos, endPos, halfExtents, boxCollider.contactOffset, SurfPhysics.groundLayerMask);
if (trace.hitCollider != null)
canUncrouch = false;
} else if (_surfer.collider.GetType () == typeof (CapsuleCollider)) {
// Capsule collider
CapsuleCollider capsuleCollider = (CapsuleCollider)_surfer.collider;
Vector3 point1 = capsuleCollider.center + Vector3.up * capsuleCollider.height * 0.5f;
Vector3 point2 = capsuleCollider.center + Vector3.down * capsuleCollider.height * 0.5f;
Vector3 startPos = capsuleCollider.transform.position;
Vector3 endPos = capsuleCollider.transform.position + (uncrouchDown ? Vector3.down : Vector3.up) * heightDifference;
Trace trace = Tracer.TraceCapsule (point1, point2, capsuleCollider.radius, startPos, endPos, capsuleCollider.contactOffset, SurfPhysics.groundLayerMask);
if (trace.hitCollider != null)
canUncrouch = false;
}
// Uncrouch
if (canUncrouch && crouchLerp <= 0.9f) {
crouching = false;
if (_surfer.collider.GetType () == typeof (BoxCollider)) {
// Box collider
BoxCollider boxCollider = (BoxCollider)_surfer.collider;
boxCollider.size = new Vector3 (boxCollider.size.x, _surfer.moveData.defaultHeight, boxCollider.size.z);
} else if (_surfer.collider.GetType () == typeof (CapsuleCollider)) {
// Capsule collider
CapsuleCollider capsuleCollider = (CapsuleCollider)_surfer.collider;
capsuleCollider.height = _surfer.moveData.defaultHeight;
}
// Move position and stuff
_surfer.moveData.origin += heightDifference / 2 * (uncrouchDown ? Vector3.down : Vector3.up);
foreach (Transform child in playerTransform) {
child.localPosition = new Vector3 (child.localPosition.x, child.localPosition.y / crouchingHeight, child.localPosition.z);
}
}
if (!canUncrouch)
crouchLerp = 1f;
}
// Changing camera position
if (!crouching)
_surfer.moveData.viewTransform.localPosition = Vector3.Lerp (_surfer.moveData.viewTransformDefaultLocalPos, _surfer.moveData.viewTransformDefaultLocalPos * crouchingHeight + Vector3.down * heightDifference * 0.5f, crouchLerp);
else
_surfer.moveData.viewTransform.localPosition = Vector3.Lerp (_surfer.moveData.viewTransformDefaultLocalPos - Vector3.down * heightDifference * 0.5f, _surfer.moveData.viewTransformDefaultLocalPos * crouchingHeight, crouchLerp);
}
void SlideMovement () {
// Gradually change direction
slideDirection += new Vector3 (groundNormal.x, 0f, groundNormal.z) * slideSpeedCurrent * _deltaTime;
slideDirection = slideDirection.normalized;
// Set direction
Vector3 slideForward = Vector3.Cross (groundNormal, Quaternion.AngleAxis (-90, Vector3.up) * slideDirection);
// Set the velocity
slideSpeedCurrent -= _config.slideFriction * _deltaTime;
slideSpeedCurrent = Mathf.Clamp (slideSpeedCurrent, 0f, _config.maximumSlideSpeed);
slideSpeedCurrent -= (slideForward * slideSpeedCurrent).y * _deltaTime * _config.downhillSlideSpeedMultiplier; // Accelerate downhill (-y = downward, - * - = +)
_surfer.moveData.velocity = slideForward * slideSpeedCurrent;
// Jump
if (_surfer.moveData.wishJump && slideSpeedCurrent < _config.minimumSlideSpeed * _config.slideSpeedMultiplier) {
Jump ();
return;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9877690760780b441aeafc5ca145fd3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,428 @@
using UnityEngine;
using Fragsurf.TraceUtil;
namespace Fragsurf.Movement {
public class SurfPhysics {
///// Fields /////
/// <summary>
/// Change this if your ground is on a different layer
/// </summary>
public static int groundLayerMask = LayerMask.GetMask (new string[] { "Default", "Ground", "Player clip" }); //(1 << 0);
private static Collider[] _colliders = new Collider [maxCollisions];
private static Vector3[] _planes = new Vector3 [maxClipPlanes];
public const float HU2M = 52.4934383202f;
private const int maxCollisions = 128;
private const int maxClipPlanes = 5;
private const int numBumps = 1;
public const float SurfSlope = 0.7f;
///// Methods /////
/// <summary>
///
/// </summary>
/// <param name="collider"></param>
/// <param name="origin"></param>
/// <param name="velocity"></param>
/// http://www.00jknight.com/blog/unity-character-controller
public static void ResolveCollisions (Collider collider, ref Vector3 origin, ref Vector3 velocity, float rigidbodyPushForce) {
// manual collision resolving
int numOverlaps = 0;
if (collider is CapsuleCollider) {
var capc = collider as CapsuleCollider;
Vector3 point1, point2;
GetCapsulePoints (capc, origin, out point1, out point2);
numOverlaps = Physics.OverlapCapsuleNonAlloc (point1, point2, capc.radius,
_colliders, groundLayerMask, QueryTriggerInteraction.Ignore);
} else if (collider is BoxCollider) {
numOverlaps = Physics.OverlapBoxNonAlloc (origin, collider.bounds.extents, _colliders,
Quaternion.identity, groundLayerMask, QueryTriggerInteraction.Ignore);
}
for (int i = 0; i < numOverlaps; i++) {
Vector3 direction;
float distance;
if (Physics.ComputePenetration (collider, origin,
Quaternion.identity, _colliders [i], _colliders [i].transform.position,
_colliders [i].transform.rotation, out direction, out distance)) {
direction.Normalize ();
Vector3 penetrationVector = direction * distance;
Vector3 velocityProjected = Vector3.Project (velocity, -direction);
velocityProjected.y = 0; // don't touch y velocity, we need it to calculate fall damage elsewhere
origin += penetrationVector;
velocity -= velocityProjected;
Rigidbody rb = _colliders [i].GetComponentInParent<Rigidbody> ();
if (rb)
if (!rb.isKinematic)
rb.AddForceAtPosition (velocityProjected * rigidbodyPushForce, origin, ForceMode.Impulse);
}
}
}
/// <summary>
///
/// </summary>
public static void Friction (ref Vector3 velocity, float stopSpeed, float friction, float deltaTime) {
var speed = velocity.magnitude;
if (speed < 0.0001905f)
return;
var drop = 0f;
// apply ground friction
var control = (speed < stopSpeed) ? stopSpeed : speed;
drop += control * friction * deltaTime;
// scale the velocity
var newspeed = speed - drop;
if (newspeed < 0)
newspeed = 0;
if (newspeed != speed) {
newspeed /= speed;
velocity *= newspeed;
}
}
/// <summary>
///
/// </summary>
/// <param name="velocity"></param>
/// <param name="wishdir"></param>
/// <param name="wishspeed"></param>
/// <param name="accel"></param>
/// <param name="airCap"></param>
/// <param name="deltaTime"></param>
/// <returns></returns>
public static Vector3 AirAccelerate (Vector3 velocity, Vector3 wishdir, float wishspeed, float accel, float airCap, float deltaTime) {
var wishspd = wishspeed;
// Cap speed
wishspd = Mathf.Min (wishspd, airCap);
// Determine veer amount
var currentspeed = Vector3.Dot (velocity, wishdir);
// See how much to add
var addspeed = wishspd - currentspeed;
// If not adding any, done.
if (addspeed <= 0)
return Vector3.zero;
// Determine acceleration speed after acceleration
var accelspeed = accel * wishspeed * deltaTime;
// Cap it
accelspeed = Mathf.Min (accelspeed, addspeed);
var result = Vector3.zero;
// Adjust pmove vel.
for (int i = 0; i < 3; i++)
result [i] += accelspeed * wishdir [i];
return result;
}
/// <summary>
///
/// </summary>
/// <param name="wishdir"></param>
/// <param name="wishspeed"></param>
/// <param name="accel"></param>
/// <returns></returns>
public static Vector3 Accelerate (Vector3 currentVelocity, Vector3 wishdir, float wishspeed, float accel, float deltaTime, float surfaceFriction) {
// See if we are changing direction a bit
var currentspeed = Vector3.Dot (currentVelocity, wishdir);
// Reduce wishspeed by the amount of veer.
var addspeed = wishspeed - currentspeed;
// If not going to add any speed, done.
if (addspeed <= 0)
return Vector3.zero;
// Determine amount of accleration.
var accelspeed = accel * deltaTime * wishspeed * surfaceFriction;
// Cap at addspeed
if (accelspeed > addspeed)
accelspeed = addspeed;
var result = Vector3.zero;
// Adjust velocity.
for (int i = 0; i < 3; i++)
result [i] += accelspeed * wishdir [i];
return result;
}
/// <summary>
///
/// </summary>
/// <param name="velocity"></param>
/// <param name="origin"></param>
/// <param name="firstDestination"></param>
/// <param name="firstTrace"></param>
/// <returns></returns>
public static int Reflect (ref Vector3 velocity, Collider collider, Vector3 origin, float deltaTime) {
float d;
var newVelocity = Vector3.zero;
var blocked = 0; // Assume not blocked
var numplanes = 0; // and not sliding along any planes
var originalVelocity = velocity; // Store original velocity
var primalVelocity = velocity;
var allFraction = 0f;
var timeLeft = deltaTime; // Total time for this movement operation.
for (int bumpcount = 0; bumpcount < numBumps; bumpcount++) {
if (velocity.magnitude == 0f)
break;
// Assume we can move all the way from the current origin to the
// end point.
var end = VectorExtensions.VectorMa (origin, timeLeft, velocity);
var trace = Tracer.TraceCollider (collider, origin, end, groundLayerMask);
allFraction += trace.fraction;
if (trace.fraction > 0) {
// actually covered some distance
originalVelocity = velocity;
numplanes = 0;
}
// If we covered the entire distance, we are done
// and can return.
if (trace.fraction == 1)
break; // moved the entire distance
// If the plane we hit has a high z component in the normal, then
// it's probably a floor
if (trace.planeNormal.y > SurfSlope)
blocked |= 1; // floor
// If the plane has a zero z component in the normal, then it's a
// step or wall
if (trace.planeNormal.y == 0)
blocked |= 2; // step / wall
// Reduce amount of m_flFrameTime left by total time left * fraction
// that we covered.
timeLeft -= timeLeft * trace.fraction;
// Did we run out of planes to clip against?
if (numplanes >= maxClipPlanes) {
// this shouldn't really happen
// Stop our movement if so.
velocity = Vector3.zero;
//Con_DPrintf("Too many planes 4\n");
break;
}
// Set up next clipping plane
_planes [numplanes] = trace.planeNormal;
numplanes++;
// modify original_velocity so it parallels all of the clip planes
//
// reflect player velocity
// Only give this a try for first impact plane because you can get yourself stuck in an acute corner by jumping in place
// and pressing forward and nobody was really using this bounce/reflection feature anyway...
if (numplanes == 1) {
for (int i = 0; i < numplanes; i++) {
if (_planes [i] [1] > SurfSlope) {
// floor or slope
return blocked;
//ClipVelocity(originalVelocity, _planes[i], ref newVelocity, 1f);
//originalVelocity = newVelocity;
} else
ClipVelocity (originalVelocity, _planes [i], ref newVelocity, 1f);
}
velocity = newVelocity;
originalVelocity = newVelocity;
} else {
int i = 0;
for (i = 0; i < numplanes; i++) {
ClipVelocity (originalVelocity, _planes [i], ref velocity, 1);
int j = 0;
for (j = 0; j < numplanes; j++) {
if (j != i) {
// Are we now moving against this plane?
if (Vector3.Dot (velocity, _planes [j]) < 0)
break;
}
}
if (j == numplanes) // Didn't have to clip, so we're ok
break;
}
// Did we go all the way through plane set
if (i != numplanes) { // go along this plane
// pmove.velocity is set in clipping call, no need to set again.
;
} else { // go along the crease
if (numplanes != 2) {
velocity = Vector3.zero;
break;
}
var dir = Vector3.Cross (_planes [0], _planes [1]).normalized;
d = Vector3.Dot (dir, velocity);
velocity = dir * d;
}
//
// if original velocity is against the original velocity, stop dead
// to avoid tiny occilations in sloping corners
//
d = Vector3.Dot (velocity, primalVelocity);
if (d <= 0f) {
//Con_DPrintf("Back\n");
velocity = Vector3.zero;
break;
}
}
}
if (allFraction == 0f)
velocity = Vector3.zero;
// Check if they slammed into a wall
//float fSlamVol = 0.0f;
//var primal2dLen = new Vector2(primal_velocity.x, primal_velocity.z).magnitude;
//var vel2dLen = new Vector2(_moveData.Velocity.x, _moveData.Velocity.z).magnitude;
//float fLateralStoppingAmount = primal2dLen - vel2dLen;
//if (fLateralStoppingAmount > PLAYER_MAX_SAFE_FALL_SPEED * 2.0f)
//{
// fSlamVol = 1.0f;
//}
//else if (fLateralStoppingAmount > PLAYER_MAX_SAFE_FALL_SPEED)
//{
// fSlamVol = 0.85f;
//}
//PlayerRoughLandingEffects(fSlamVol);
return blocked;
}
/// <summary>
///
/// </summary>
/// <param name="input"></param>
/// <param name="normal"></param>
/// <param name="output"></param>
/// <param name="overbounce"></param>
/// <returns></returns>
public static int ClipVelocity (Vector3 input, Vector3 normal, ref Vector3 output, float overbounce) {
var angle = normal [1];
var blocked = 0x00; // Assume unblocked.
if (angle > 0) // If the plane that is blocking us has a positive z component, then assume it's a floor.
blocked |= 0x01; //
if (angle == 0) // If the plane has no Z, it is vertical (wall/step)
blocked |= 0x02; //
// Determine how far along plane to slide based on incoming direction.
var backoff = Vector3.Dot (input, normal) * overbounce;
for (int i = 0; i < 3; i++) {
var change = normal [i] * backoff;
output [i] = input [i] - change;
}
// iterate once to make sure we aren't still moving through the plane
float adjust = Vector3.Dot (output, normal);
if (adjust < 0.0f) {
output -= (normal * adjust);
// Msg( "Adjustment = %lf\n", adjust );
}
// Return blocking flags.
return blocked;
}
/// <summary>
///
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
public static void GetCapsulePoints (CapsuleCollider capc, Vector3 origin, out Vector3 p1, out Vector3 p2) {
var distanceToPoints = capc.height / 2f - capc.radius;
p1 = origin + capc.center + Vector3.up * distanceToPoints;
p2 = origin + capc.center - Vector3.up * distanceToPoints;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 82894b74fd05a584385e994a8297661f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,77 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAiming : MonoBehaviour {
[Header ("References")]
public Transform bodyTransform = null;
[Header ("Sensitivity")]
public float sensitivityMultiplier = 1f;
public float horizontalSensitivity = 1f;
public float verticalSensitivity = 1f;
[Header ("Restrictions")]
public float minYRotation = -90f;
public float maxYRotation = 90f;
// Rotation values
[HideInInspector] public float bodyRotation = 0f;
[HideInInspector] public Vector3 cameraRotation = Vector3.zero;
private float bodyRotationTemp = 0f;
private Vector3 cameraRotationTemp = Vector3.zero;
// Leaning
[HideInInspector] public float leanInput = 0f;
// Sway
[HideInInspector] public float sway = 0f;
void Start () {
// Lock the mouse
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update () {
Vector3 eulerAngles = transform.localEulerAngles;
// Remove previous rotation
eulerAngles = new Vector3 (eulerAngles.x - cameraRotationTemp.x, eulerAngles.y, eulerAngles.z - cameraRotationTemp.z);
bodyTransform.eulerAngles -= cameraRotationTemp.y * Vector3.up;
// Fix pausing
if (Time.timeScale == 0f)
return;
// Input
float xMovement = Input.GetAxis ("Mouse X") * horizontalSensitivity * sensitivityMultiplier;
float yMovement = -Input.GetAxis ("Mouse Y") * verticalSensitivity * sensitivityMultiplier;
// Rotate camera
cameraRotation = new Vector3 (Mathf.Clamp (cameraRotation.x + yMovement, minYRotation, maxYRotation),
cameraRotation.y + xMovement,
cameraRotation.z + sway);
cameraRotation.z = Mathf.Lerp (cameraRotation.z, 0f, Time.deltaTime * 3f);
// Apply rotation
Vector3 clampedRotation = new Vector3 (Mathf.Clamp (cameraRotation.x, minYRotation, maxYRotation),
cameraRotation.y,
cameraRotation.z);
eulerAngles = new Vector3 (eulerAngles.x + clampedRotation.x, eulerAngles.y, eulerAngles.z + clampedRotation.z);
bodyTransform.eulerAngles += Vector3.Scale (clampedRotation, new Vector3 (0f, 1f, 0f));
cameraRotationTemp = clampedRotation;
// Remove recoil
transform.localEulerAngles = eulerAngles;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 604093a680e6d5a488206647cc35be23
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 94e9fff1435e72045a8916637b54c2a8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using UnityEngine;
namespace Fragsurf.TraceUtil {
public struct Trace {
public Vector3 startPos;
public Vector3 endPos;
public float fraction;
public bool startSolid;
public Collider hitCollider;
public Vector3 hitPoint;
public Vector3 planeNormal;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3d79906c8a32f894eac47445c9814b61
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,115 @@
using UnityEngine;
namespace Fragsurf.TraceUtil {
public class Tracer {
/// <summary>
///
/// </summary>
/// <param name="collider"></param>
/// <param name="origin"></param>
/// <param name="end"></param>
/// <param name="layerMask"></param>
/// <returns></returns>
public static Trace TraceCollider (Collider collider, Vector3 origin, Vector3 end, int layerMask) {
if (collider is BoxCollider) {
// Box collider trace
return TraceBox (origin, end, collider.bounds.extents, collider.contactOffset, layerMask);
} else if (collider is CapsuleCollider) {
// Capsule collider trace
var capc = (CapsuleCollider)collider;
Vector3 point1, point2;
Movement.SurfPhysics.GetCapsulePoints (capc, origin, out point1, out point2);
return TraceCapsule (point1, point2, capc.radius, origin, end, capc.contactOffset, layerMask);
}
throw new System.NotImplementedException ("Trace missing for collider: " + collider.GetType ());
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static Trace TraceCapsule (Vector3 point1, Vector3 point2, float radius, Vector3 start, Vector3 destination, float contactOffset, int layerMask) {
var result = new Trace () {
startPos = start,
endPos = destination
};
var longSide = Mathf.Sqrt (contactOffset * contactOffset + contactOffset * contactOffset);
radius *= (1f - contactOffset);
var direction = (destination - start).normalized;
var maxDistance = Vector3.Distance (start, destination) + longSide;
RaycastHit hit;
if (Physics.CapsuleCast (
point1: point1,
point2: point2,
radius: radius,
direction: direction,
hitInfo: out hit,
maxDistance: maxDistance,
layerMask: layerMask,
queryTriggerInteraction: QueryTriggerInteraction.Ignore)) {
result.fraction = hit.distance / maxDistance;
result.hitCollider = hit.collider;
result.hitPoint = hit.point;
result.planeNormal = hit.normal;
} else
result.fraction = 1;
return result;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static Trace TraceBox (Vector3 start, Vector3 destination, Vector3 extents, float contactOffset, int layerMask) {
var result = new Trace () {
startPos = start,
endPos = destination
};
var longSide = Mathf.Sqrt (contactOffset * contactOffset + contactOffset * contactOffset);
var direction = (destination - start).normalized;
var maxDistance = Vector3.Distance (start, destination) + longSide;
extents *= (1f - contactOffset);
RaycastHit hit;
if (Physics.BoxCast (center: start,
halfExtents: extents,
direction: direction,
orientation: Quaternion.identity,
maxDistance: maxDistance,
hitInfo: out hit,
layerMask: layerMask,
queryTriggerInteraction: QueryTriggerInteraction.Ignore)) {
result.fraction = hit.distance / maxDistance;
result.hitCollider = hit.collider;
result.hitPoint = hit.point;
result.planeNormal = hit.normal;
} else
result.fraction = 1;
return result;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b42ff46330f0b0d4696f4b054b34550f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Water : MonoBehaviour {
// This component is separate from the player's underwater movement.
// Feel free to add whatever you want in here, like a rigidbody buoyancy/floating system or something.
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c652f03f4545c86499de323569052da5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: