-
Notifications
You must be signed in to change notification settings - Fork 1
/
KinematicDecoupleMovementControl.cs
91 lines (75 loc) · 3.77 KB
/
KinematicDecoupleMovementControl.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using MxM;
using MxMGameplay;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static KinematicControllerWrapper;
public class KinematicDecoupleMovementControl : MonoBehaviour
{
private MyTrajectoryGenerator m_trajectoryGenerator;
private MxMAnimationDecoupler m_animDecoupler;
private GenericControllerWrapper m_charController;
MxMTrajectoryGeneratorBase trajectoryGenerator;
public KinematicControllerWrapper _wrapper;
private void Awake()
{
m_trajectoryGenerator = GetComponentInChildren<MyTrajectoryGenerator>();
m_animDecoupler = GetComponent<MxMAnimationDecoupler>();
m_charController = GetComponent<GenericControllerWrapper>();
_wrapper = GetComponent<KinematicControllerWrapper>();
if (m_trajectoryGenerator == null)
{
Debug.LogError("ExampleDecoupleMovementControl cannot find a trajectory generator component. Disabling component");
enabled = false;
return;
}
if (m_animDecoupler == null)
{
Debug.LogError("ExampleDecoupleMovementControl cannot find a MxMAnimationDecoupler component. Disabling component");
enabled = false;
return;
}
if (m_charController == null)
{
Debug.LogError("ExampleDecoupleMovementControl canno find a GenericControllerWrapper component. Disabling component");
enabled = false;
return;
}
}
public void UpdateMovementLogic(float a_deltaTime)
{
//For this example controller we just extract the motion at the start of the trajectory.
//Here I take the first 0.3s of the trajectory
/*if (_wrapper.GetControlState() == ControlState.UnderDirectControl)
{
trajectoryGenerator = m_trajectoryGenerator;
}
else if (_wrapper.GetControlState() == ControlState.ACTurning)
{
trajectoryGenerator = m_kinematicTrajectoryGenerator;
}
else
{
trajectoryGenerator = m_kinematicTrajectoryGenerator;
}*/
var motion = m_trajectoryGenerator.ExtractMotion(0.3f);
Quaternion rotDelta = Quaternion.Inverse(transform.rotation) * Quaternion.AngleAxis(motion.angleDelta, Vector3.up);
motion.angleDelta = rotDelta.eulerAngles.y;
//To get the average motion of that 0.3s trajectory per Time.deltaTime we multiply by (Time.deltaTime / 0.3f)
motion.moveDelta *= (a_deltaTime / 0.3f);
motion.angleDelta *= (a_deltaTime / 0.3f);
//The movement extracted from the trajectory is then blended in based on Root motion blending settings on the MxMAnimationDecoupler
//You only need to do this if you want root motion blending
motion = m_animDecoupler.CalculateRootMotionBlending(motion.moveDelta, motion.angleDelta, m_trajectoryGenerator.HasMovementInput());
//Now we apply gravity on top of the root motion blended movement delta. This can be done manually or use built in functionality
//if (!m_charController.IsGrounded)
motion.moveDelta.y = m_animDecoupler.CalculateGravityMoveDelta(a_deltaTime);
//Now that we have the final move delta we can apply it to our generic controller wrapper
m_charController.Move(motion.moveDelta);
//For this particular movement control I've decided that the rotation of the capsule will always be the same as the model rotation
//rotation is not particularly important for the controller itself so its relatively trivial. Best to keep it in line with what
//the player is seeing.
//m_charController.Rotate(Quaternion.AngleAxis(motion.angleDelta, Vector3.up));
//transform.rotation = m_trajectoryGenerator.transform.rotation;
}
}