using System;
using UnityEngine;
using Framework.Support;
using Framework.Services;
namespace Framework.Actors {
/// Stores the movement range of an actor's head
///
/// This is accessed by head movement components such as
/// the and the
///
/// to limit how far these components will rotate an actor's head. Sharing it
/// this way allows AI characters that can be "possessed" by a human
/// player to keep their settings even when switching between different head controllers.
///
public class HeadMovementRange : ScriptComponent {
/// How far the user can move the characters head left and right
public Range YawRange = new Range(-80.0f, 80.0f);
/// How far the user can move the characters head up and down
public Range PitchRange = new Range(-40.0f, 85.0f);
/// Downward pitch limit for the head based on its yaw
///
/// The head can look further downward then centered than it can when
/// look to the side since the chin would be blocked by the shoulders.
/// This curve will ensure that mouse users can look into their shoulders
/// while turning the head.
///
public AnimationCurve MousePitchLimitByYaw = CreateDefaultPitchLimitCurve();
/// Creates the default pitch limit curve for mouse users
/// The default pitch limit curve for mouse users
///
/// There are different limits for the pitch depending on the head's yaw so that
/// the head will be naturally limited from looking down when the chin would
/// sit on the character's shoulder.
///
private static AnimationCurve CreateDefaultPitchLimitCurve() {
return new AnimationCurve(
new Keyframe(-90.0f, 30.0f),
new Keyframe(-30.0f, 90.0f),
new Keyframe(+30.0f, 90.0f),
new Keyframe(+90.0f, 30.0f)
);
}
/// Clamps pitch and yaw by the limits set up for the head
/// Pitch angle of the head that will be clamped
/// Yaw angle of the head that will be clamped
public void ClampPitchAndYaw(ref float pitch, ref float yaw) {
yaw = Mathf.Clamp(
yaw,
this.YawRange.Start,
this.YawRange.End
);
pitch = Mathf.Clamp(
pitch,
this.PitchRange.Start,
this.PitchRange.End
);
// Also clamp pitch by the pitch-by-yaw limit curve if present
if(this.MousePitchLimitByYaw != null) {
float maximumPitch = this.MousePitchLimitByYaw.Evaluate(yaw);
if(pitch > maximumPitch) {
pitch = maximumPitch;
}
}
}
}
} // namespace Framework.Actors