This commit is contained in:
2026-06-09 09:18:17 +07:00
parent 3578a2750c
commit 71a096556a
5777 changed files with 6675 additions and 13 deletions

View File

@@ -1,48 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility
{
/// <summary>
/// Static class defining information about the asset.
/// </summary>
public static class AssetInfo
{
private static string s_Version = "2.2.5";
public static string Version { get { return s_Version; } }
public static string Name
{
get
{
#pragma warning disable 0162
#if FIRST_PERSON_CONTROLLER && THIRD_PERSON_CONTROLLER && ULTIMATE_CHARACTER_CONTROLLER_SHOOTER && ULTIMATE_CHARACTER_CONTROLLER_MELEE
return "Ultimate Character Controller";
#endif
#if FIRST_PERSON_CONTROLLER && ULTIMATE_CHARACTER_CONTROLLER_SHOOTER && ULTIMATE_CHARACTER_CONTROLLER_MELEE
return "First Person Controller";
#endif
#if THIRD_PERSON_CONTROLLER && ULTIMATE_CHARACTER_CONTROLLER_SHOOTER && ULTIMATE_CHARACTER_CONTROLLER_MELEE
return "Third Person Controller";
#endif
#if FIRST_PERSON_CONTROLLER && ULTIMATE_CHARACTER_CONTROLLER_SHOOTER
return "Ultimate First Person Shooter";
#endif
#if FIRST_PERSON_CONTROLLER && ULTIMATE_CHARACTER_CONTROLLER_MELEE
return "Ultimate First Person Melee";
#endif
#if THIRD_PERSON_CONTROLLER && ULTIMATE_CHARACTER_CONTROLLER_SHOOTER
return "Ultimate Third Person Shooter";
#endif
#if THIRD_PERSON_CONTROLLER && ULTIMATE_CHARACTER_CONTROLLER_MELEE
return "Ultimate Third Person Melee";
#endif
return string.Empty;
#pragma warning restore 0162
}
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 12f2707fbd545fc4fbc3f704a078def7
timeCreated: 1485983569
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -1,754 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility.Builders
{
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;
using Opsive.UltimateCharacterController.Character.Abilities.Items;
using Opsive.UltimateCharacterController.Game;
using Opsive.UltimateCharacterController.StateSystem;
using System;
using System.Collections.Generic;
/// <summary>
/// Adds and serializes UltimateCharacterLocomotion abilities.
/// </summary>
public static class AbilityBuilder
{
private static Dictionary<Type, UnityEngine.RequireComponent[]> s_RequiredComponents = new Dictionary<Type, UnityEngine.RequireComponent[]>();
private static Dictionary<Type, DefaultInputName[]> s_DefaultInputName = new Dictionary<Type, DefaultInputName[]>();
private static Dictionary<Type, DefaultStartType> s_DefaultStartType = new Dictionary<Type, DefaultStartType>();
private static Dictionary<Type, DefaultStopType> s_DefaultStopType = new Dictionary<Type, DefaultStopType>();
private static Dictionary<Type, DefaultAbilityIndex> s_DefaultAbilityIndex = new Dictionary<Type, DefaultAbilityIndex>();
private static Dictionary<Type, DefaultAbilityIntData> s_DefaultAbilityIntData = new Dictionary<Type, DefaultAbilityIntData>();
private static Dictionary<Type, DefaultItemStateIndex> s_DefaultItemStateIndex = new Dictionary<Type, DefaultItemStateIndex>();
private static Dictionary<Type, DefaultState> s_DefaultState = new Dictionary<Type, DefaultState>();
private static Dictionary<Type, DefaultAllowPositionalInput> s_DefaultAllowPositionalInput = new Dictionary<Type, DefaultAllowPositionalInput>();
private static Dictionary<Type, DefaultAllowRotationalInput> s_DefaultAllowRotationalInput = new Dictionary<Type, DefaultAllowRotationalInput>();
private static Dictionary<Type, DefaultUseGravity> s_DefaultUseGravity = new Dictionary<Type, DefaultUseGravity>();
private static Dictionary<Type, DefaultUseRootMotionPosition> s_DefaultUseRootMotionPosition = new Dictionary<Type, DefaultUseRootMotionPosition>();
private static Dictionary<Type, DefaultUseRootMotionRotation> s_DefaultUseRootMotionRotation = new Dictionary<Type, DefaultUseRootMotionRotation>();
private static Dictionary<Type, DefaultDetectHorizontalCollisions> s_DefaultDetectHorizontalCollisions = new Dictionary<Type, DefaultDetectHorizontalCollisions>();
private static Dictionary<Type, DefaultDetectVerticalCollisions> s_DefaultDetectVerticalCollisions = new Dictionary<Type, DefaultDetectVerticalCollisions>();
private static Dictionary<Type, DefaultObjectDetection> s_DefaultObjectDetection = new Dictionary<Type, DefaultObjectDetection>();
private static Dictionary<Type, DefaultUseLookDirection> s_DefaultUseLookDirection = new Dictionary<Type, DefaultUseLookDirection>();
private static Dictionary<Type, DefaultCastOffset> s_DefaultCastOffset = new Dictionary<Type, DefaultCastOffset>();
private static Dictionary<Type, DefaultEquippedSlots> s_DefaultEquippedSlots = new Dictionary<Type, DefaultEquippedSlots>();
private static Dictionary<Type, DefaultReequipSlots> s_DefaultReequipSlots = new Dictionary<Type, DefaultReequipSlots>();
private static Dictionary<Type, AddState[]> s_AddStates = new Dictionary<Type, AddState[]>();
/// <summary>
/// Adds the ability with the specified type.
/// </summary>
/// <param name="characterLocomotion">The character to add the ability to.</param>
/// <param name="abilityType">The type of ability to add.</param>
/// <returns>The added ability.</returns>
public static Ability AddAbility(UltimateCharacterLocomotion characterLocomotion, Type abilityType)
{
if (typeof(ItemAbility).IsAssignableFrom(abilityType)) {
return AddItemAbility(characterLocomotion, abilityType);
}
var abilities = characterLocomotion.GetSerializedAbilities();
var index = abilities == null ? 0 : abilities.Length;
return AddAbility(characterLocomotion, abilityType, index);
}
/// <summary>
/// Adds the ability with the specified type.
/// </summary>
/// <param name="characterLocomotion">The character to add the ability to.</param>
/// <param name="abilityType">The type of ability to add.</param>
/// <param name="index">The index to add the ability to.</param>
/// <returns>The added ability.</returns>
public static Ability AddAbility(UltimateCharacterLocomotion characterLocomotion, Type abilityType, int index)
{
var abilities = characterLocomotion.GetSerializedAbilities();
if (abilities == null) {
abilities = new Ability[1];
} else {
Array.Resize(ref abilities, abilities.Length + 1);
}
var ability = Activator.CreateInstance(abilityType) as Ability;
// Assign the default values specified by any added attribtes.
SetAbilityDefaultValues(ability);
for (int i = abilities.Length - 1; i > index; --i) {
abilities[i] = abilities[i - 1];
}
abilities[index] = ability;
characterLocomotion.Abilities = abilities;
SerializeAbilities(characterLocomotion);
// The ability may require other components in order to operate.
var requiredComponents = GetRequiredComponents(abilityType);
if (requiredComponents != null && requiredComponents.Length > 0) {
for (int i = 0; i < requiredComponents.Length; ++i) {
characterLocomotion.gameObject.AddComponent(requiredComponents[i].m_Type0);
}
}
return ability;
}
/// <summary>
/// Adds the item ability with the specified type.
/// </summary>
/// <param name="characterLocomotion">The character to add the ability to.</param>
/// <param name="abilityType">The type of ability to add.</param>
/// <returns>The added ability.</returns>
public static ItemAbility AddItemAbility(UltimateCharacterLocomotion characterLocomotion, Type abilityType)
{
var itemAbilities = characterLocomotion.GetSerializedItemAbilities();
var index = itemAbilities == null ? 0 : itemAbilities.Length;
return AddItemAbility(characterLocomotion, abilityType, index);
}
/// <summary>
/// Adds the item ability with the specified type.
/// </summary>
/// <param name="characterLocomotion">The character to add the ability to.</param>
/// <param name="abilityType">The type of ability to add.</param>
/// <returns>The added ability.</returns>
public static ItemAbility AddItemAbility(UltimateCharacterLocomotion characterLocomotion, Type abilityType, int index)
{
var itemAbilities = characterLocomotion.GetSerializedItemAbilities();
if (itemAbilities == null) {
itemAbilities = new ItemAbility[1];
} else {
Array.Resize(ref itemAbilities, itemAbilities.Length + 1);
}
var itemAbility = Activator.CreateInstance(abilityType) as ItemAbility;
// Assign the default values specified by any added attribtes.
SetAbilityDefaultValues(itemAbility);
for (int i = itemAbilities.Length - 1; i > index; --i) {
itemAbilities[i] = itemAbilities[i - 1];
}
itemAbilities[itemAbilities.Length - 1] = itemAbility;
characterLocomotion.ItemAbilities = itemAbilities;
SerializeItemAbilities(characterLocomotion);
return itemAbility;
}
/// <summary>
/// Serialize all of the abilities to the AbilityData array.
/// </summary>
/// <param name="characterLocomotion">The character to serialize.</param>
public static void SerializeAbilities(UltimateCharacterLocomotion characterLocomotion)
{
var abilities = characterLocomotion.Abilities == null ? new List<Ability>() : new List<Ability>(characterLocomotion.Abilities);
characterLocomotion.AbilityData = Shared.Utility.Serialization.Serialize<Ability>(abilities);
characterLocomotion.Abilities = abilities.ToArray();
#if UNITY_EDITOR
UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(characterLocomotion);
#endif
}
/// <summary>
/// Serialize all of the item abilities to the ItemAbilityData array.
/// </summary>
/// <param name="characterLocomotion">The character to serialize.</param>
public static void SerializeItemAbilities(UltimateCharacterLocomotion characterLocomotion)
{
var itemAbilities = characterLocomotion.ItemAbilities == null ? new List<ItemAbility>() : new List<ItemAbility>(characterLocomotion.ItemAbilities);
characterLocomotion.ItemAbilityData = Shared.Utility.Serialization.Serialize<ItemAbility>(itemAbilities);
characterLocomotion.ItemAbilities = itemAbilities.ToArray();
#if UNITY_EDITOR
UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(characterLocomotion);
#endif
}
/// <summary>
/// Removes the specified ability from the ability array.
/// </summary>
/// <param name="characterLocomotion">The character to remove the ability from.</param>
public static void RemoveAbility<T>(UltimateCharacterLocomotion characterLocomotion) where T : Ability
{
var ability = characterLocomotion.GetAbility<T>();
if (ability != null) {
RemoveAbility(characterLocomotion, ability);
}
}
/// <summary>
/// Removes the specified ability from the ability array.
/// </summary>
/// <param name="characterLocomotion">The character to remove the ability from.</param>
/// <param name="ability">The ability to remove.</param>
public static void RemoveAbility(UltimateCharacterLocomotion characterLocomotion, Ability ability)
{
if (ability == null) {
return;
}
if (typeof(ItemAbility).IsAssignableFrom(ability.GetType())) {
RemoveItemAbility(characterLocomotion, ability);
return;
}
var abilities = new Ability[characterLocomotion.Abilities.Length - 1];
var index = 0;
for (int i = 0; i < characterLocomotion.Abilities.Length; ++i) {
if (characterLocomotion.Abilities[i] != ability) {
abilities[index] = characterLocomotion.Abilities[i];
index++;
}
}
characterLocomotion.Abilities = abilities;
SerializeAbilities(characterLocomotion);
}
/// <summary>
/// Removes the specified ability from the item ability array.
/// </summary>
/// <param name="characterLocomotion">The character to remove the ability from.</param>
/// <param name="ability">The ability to remove.</param>
public static void RemoveItemAbility(UltimateCharacterLocomotion characterLocomotion, Ability ability)
{
var abilities = new ItemAbility[characterLocomotion.ItemAbilities.Length - 1];
var index = 0;
for (int i = 0; i < characterLocomotion.ItemAbilities.Length; ++i) {
if (characterLocomotion.ItemAbilities[i] != ability) {
abilities[index] = characterLocomotion.ItemAbilities[i];
}
}
characterLocomotion.ItemAbilities = abilities;
SerializeItemAbilities(characterLocomotion);
}
/// <summary>
/// Returns the RequiredComponent of the specified ability type.
/// </summary>
/// <param name="abilityType">The type of ability.</param>
/// <returns>The RequiredComponent of the specified ability type. Can be null.</returns>
private static UnityEngine.RequireComponent[] GetRequiredComponents(Type type)
{
UnityEngine.RequireComponent[] requiredComponents;
if (s_RequiredComponents.TryGetValue(type, out requiredComponents)) {
return requiredComponents;
}
if (type.GetCustomAttributes(typeof(UnityEngine.RequireComponent), true).Length > 0) {
requiredComponents = type.GetCustomAttributes(typeof(UnityEngine.RequireComponent), true) as UnityEngine.RequireComponent[];
}
s_RequiredComponents.Add(type, requiredComponents);
return requiredComponents;
}
/// <summary>
/// Sets the default values for the ability.
/// </summary>
/// <param name="ability">The ability to set the default values of.</param>
private static void SetAbilityDefaultValues(Ability ability)
{
var abilityType = ability.GetType();
var defaultInputNames = GetDefaultInputNames(abilityType);
if (defaultInputNames != null && defaultInputNames.Length > 0) {
ability.InputNames = new string[defaultInputNames.Length];
for (int i = 0; i < defaultInputNames.Length; ++i) {
ability.InputNames[defaultInputNames[i].Index] = defaultInputNames[i].InputName;
}
}
var defaultStartType = GetDefaultStartType(abilityType);
if (defaultStartType != null) {
ability.StartType = defaultStartType.StartType;
}
var defaultStopType = GetDefaultStopType(abilityType);
if (defaultStopType != null) {
ability.StopType = defaultStopType.StopType;
}
var defaultAbilityIndex = GetDefaultAbilityIndex(abilityType);
if (defaultAbilityIndex != null) {
ability.AbilityIndexParameter = defaultAbilityIndex.Value;
}
var defaultAbilityIntData = GetDefaultAbilityIntData(abilityType);
if (defaultAbilityIntData != null) {
ability.AbilityIntData = defaultAbilityIntData.Value;
}
var defaultState = GetDefaultState(abilityType);
if (defaultState != null) {
ability.State = defaultState.Value;
}
if (typeof(ItemAbility).IsAssignableFrom(abilityType)) {
var defaultItemStateIndex = GetDefaultItemStateIndex(abilityType);
if (defaultItemStateIndex != null) {
(ability as ItemAbility).ItemStateIndex = defaultItemStateIndex.Value;
}
}
var defaultAllowPositionalInput = GetDefaultAllowPositionalInput(abilityType);
if (defaultAllowPositionalInput != null) {
ability.AllowPositionalInput = defaultAllowPositionalInput.Value;
}
var defaultAllowRotationalInput = GetDefaultAllowRotationalInput(abilityType);
if (defaultAllowRotationalInput != null) {
ability.AllowRotationalInput = defaultAllowRotationalInput.Value;
}
var defaultUseGravity = GetDefaultUseGravity(abilityType);
if (defaultUseGravity != null) {
ability.UseGravity = defaultUseGravity.Value;
}
var defaultUseRootMotionPosition = GetDefaultUseRootMotionPosition(abilityType);
if (defaultUseRootMotionPosition != null) {
ability.UseRootMotionPosition = defaultUseRootMotionPosition.Value;
}
var defaultUseRootMotionRotation = GetDefaultUseRootMotionRotation(abilityType);
if (defaultUseRootMotionRotation != null) {
ability.UseRootMotionRotation = defaultUseRootMotionRotation.Value;
}
var defaultDetectHorizontalCollisions = GetDefaultDetectHorizontalCollisions(abilityType);
if (defaultDetectHorizontalCollisions != null) {
ability.DetectHorizontalCollisions = defaultDetectHorizontalCollisions.Value;
}
var defaultDetectVerticalCollisions = GetDefaultDetectVerticalCollisions(abilityType);
if (defaultDetectVerticalCollisions != null) {
ability.DetectVerticalCollisions = defaultDetectVerticalCollisions.Value;
}
if (ability is DetectObjectAbilityBase) {
var defaultObjectDetection = GetDefaultObjectDetection(abilityType);
if (defaultObjectDetection != null) {
(ability as DetectObjectAbilityBase).ObjectDetection = defaultObjectDetection.Value;
// If the detection layer is a trigger then the layer should include the ignore layer.
if ((defaultObjectDetection.Value & DetectObjectAbilityBase.ObjectDetectionMode.Trigger) != 0) {
(ability as DetectObjectAbilityBase).DetectLayers |= 1 << LayerManager.IgnoreRaycast;
}
}
var defaultUseLookDirection = GetDefaultUseLookDirection(abilityType);
if (defaultUseLookDirection != null) {
(ability as DetectObjectAbilityBase).UseLookDirection = defaultUseLookDirection.Value;
}
var defaultCastOffset = GetDefaultCastOffset(abilityType);
if (defaultCastOffset != null) {
(ability as DetectObjectAbilityBase).CastOffset = defaultCastOffset.Value;
}
var defaultEquippedSlots = GetDefaultEquippedSlots(abilityType);
if (defaultEquippedSlots != null) {
(ability as DetectObjectAbilityBase).AllowEquippedSlotsMask = defaultEquippedSlots.Value;
}
var defaultReequipSlots = GetDefaultReequipSlots(abilityType);
if (defaultReequipSlots != null) {
(ability as DetectObjectAbilityBase).ReequipSlots = defaultReequipSlots.Value;
}
}
#if UNITY_EDITOR
var addStates = GetAddStates(abilityType);
if (addStates != null && addStates.Length > 0) {
var states = ability.States;
var addedStates = 0;
var stateLength = states.Length;
Array.Resize(ref states, stateLength + addStates.Length);
// Default must always be at the end.
states[states.Length - 1] = states[0];
for (int i = 0; i < addStates.Length; ++i) {
var presetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(addStates[i].PresetGUID);
if (!string.IsNullOrEmpty(presetPath)) {
var preset = UnityEditor.AssetDatabase.LoadAssetAtPath(presetPath, typeof(PersistablePreset)) as PersistablePreset;
if (preset != null) {
states[i] = new State(addStates[i].Name, preset, null);
addedStates++;
}
}
}
if (addedStates != addStates.Length) {
Array.Resize(ref states, stateLength + addedStates);
}
ability.States = states;
}
#endif
}
/// <summary>
/// Returns the DefaultInputName of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultInputName of the specified ability type. Can be null.</returns>
private static DefaultInputName[] GetDefaultInputNames(Type type)
{
DefaultInputName[] defaultInputNames;
if (s_DefaultInputName.TryGetValue(type, out defaultInputNames)) {
return defaultInputNames;
}
if (type.GetCustomAttributes(typeof(DefaultInputName), true).Length > 0) {
defaultInputNames = type.GetCustomAttributes(typeof(DefaultInputName), true) as DefaultInputName[];
}
s_DefaultInputName.Add(type, defaultInputNames);
return defaultInputNames;
}
/// <summary>
/// Returns the DefaultStartType of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultStartType of the specified ability type. Can be null.</returns>
private static DefaultStartType GetDefaultStartType(Type type)
{
DefaultStartType defaultStartType;
if (s_DefaultStartType.TryGetValue(type, out defaultStartType)) {
return defaultStartType;
}
if (type.GetCustomAttributes(typeof(DefaultStartType), true).Length > 0) {
defaultStartType = type.GetCustomAttributes(typeof(DefaultStartType), true)[0] as DefaultStartType;
}
s_DefaultStartType.Add(type, defaultStartType);
return defaultStartType;
}
/// <summary>
/// Returns the DefaultStopType of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultStopType of the specified ability type. Can be null.</returns>
private static DefaultStopType GetDefaultStopType(Type type)
{
DefaultStopType defaultStopType;
if (s_DefaultStopType.TryGetValue(type, out defaultStopType)) {
return defaultStopType;
}
if (type.GetCustomAttributes(typeof(DefaultStopType), true).Length > 0) {
defaultStopType = type.GetCustomAttributes(typeof(DefaultStopType), true)[0] as DefaultStopType;
}
s_DefaultStopType.Add(type, defaultStopType);
return defaultStopType;
}
/// <summary>
/// Returns the DefaultAbilityIndex of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultAbilityIndex of the specified ability type. Can be null.</returns>
private static DefaultAbilityIndex GetDefaultAbilityIndex(Type type)
{
DefaultAbilityIndex defaultAbilityIndex;
if (s_DefaultAbilityIndex.TryGetValue(type, out defaultAbilityIndex)) {
return defaultAbilityIndex;
}
if (type.GetCustomAttributes(typeof(DefaultAbilityIndex), true).Length > 0) {
defaultAbilityIndex = type.GetCustomAttributes(typeof(DefaultAbilityIndex), true)[0] as DefaultAbilityIndex;
}
s_DefaultAbilityIndex.Add(type, defaultAbilityIndex);
return defaultAbilityIndex;
}
/// <summary>
/// Returns the DefaultAbilityIntData of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultAbilityIntData of the specified ability type. Can be null.</returns>
private static DefaultAbilityIntData GetDefaultAbilityIntData(Type type)
{
DefaultAbilityIntData defaultStateIndex;
if (s_DefaultAbilityIntData.TryGetValue(type, out defaultStateIndex)) {
return defaultStateIndex;
}
if (type.GetCustomAttributes(typeof(DefaultAbilityIntData), true).Length > 0) {
defaultStateIndex = type.GetCustomAttributes(typeof(DefaultAbilityIntData), true)[0] as DefaultAbilityIntData;
}
s_DefaultAbilityIntData.Add(type, defaultStateIndex);
return defaultStateIndex;
}
/// <summary>
/// Returns the DefaultItemStateIndex of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultItemStateIndex of the specified ability type. Can be null.</returns>
private static DefaultItemStateIndex GetDefaultItemStateIndex(Type type)
{
DefaultItemStateIndex defaultItemStateIndex;
if (s_DefaultItemStateIndex.TryGetValue(type, out defaultItemStateIndex)) {
return defaultItemStateIndex;
}
if (type.GetCustomAttributes(typeof(DefaultItemStateIndex), true).Length > 0) {
defaultItemStateIndex = type.GetCustomAttributes(typeof(DefaultItemStateIndex), true)[0] as DefaultItemStateIndex;
}
s_DefaultItemStateIndex.Add(type, defaultItemStateIndex);
return defaultItemStateIndex;
}
/// <summary>
/// Returns the DefaultState of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultState of the specified ability type. Can be null.</returns>
private static DefaultState GetDefaultState(Type type)
{
DefaultState defaultState;
if (s_DefaultState.TryGetValue(type, out defaultState)) {
return defaultState;
}
if (type.GetCustomAttributes(typeof(DefaultState), true).Length > 0) {
defaultState = type.GetCustomAttributes(typeof(DefaultState), true)[0] as DefaultState;
}
s_DefaultState.Add(type, defaultState);
return defaultState;
}
/// <summary>
/// Returns the DefaultAllowPositionalInput of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultAllowPositionalInput of the specified ability type. Can be null.</returns>
private static DefaultAllowPositionalInput GetDefaultAllowPositionalInput(Type type)
{
DefaultAllowPositionalInput defaultAllowPositionalInput;
if (s_DefaultAllowPositionalInput.TryGetValue(type, out defaultAllowPositionalInput)) {
return defaultAllowPositionalInput;
}
if (type.GetCustomAttributes(typeof(DefaultAllowPositionalInput), true).Length > 0) {
defaultAllowPositionalInput = type.GetCustomAttributes(typeof(DefaultAllowPositionalInput), true)[0] as DefaultAllowPositionalInput;
}
s_DefaultAllowPositionalInput.Add(type, defaultAllowPositionalInput);
return defaultAllowPositionalInput;
}
/// <summary>
/// Returns the DefaultAllowRotationalInput of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultAllowRotationalInput of the specified ability type. Can be null.</returns>
private static DefaultAllowRotationalInput GetDefaultAllowRotationalInput(Type type)
{
DefaultAllowRotationalInput defaultAllowRotationalInput;
if (s_DefaultAllowRotationalInput.TryGetValue(type, out defaultAllowRotationalInput)) {
return defaultAllowRotationalInput;
}
if (type.GetCustomAttributes(typeof(DefaultAllowRotationalInput), true).Length > 0) {
defaultAllowRotationalInput = type.GetCustomAttributes(typeof(DefaultAllowRotationalInput), true)[0] as DefaultAllowRotationalInput;
}
s_DefaultAllowRotationalInput.Add(type, defaultAllowRotationalInput);
return defaultAllowRotationalInput;
}
/// <summary>
/// Returns the DefaultUseGravity of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultUseGravity of the specified ability type. Can be null.</returns>
private static DefaultUseGravity GetDefaultUseGravity(Type type)
{
DefaultUseGravity defaultUseGravity;
if (s_DefaultUseGravity.TryGetValue(type, out defaultUseGravity)) {
return defaultUseGravity;
}
if (type.GetCustomAttributes(typeof(DefaultUseGravity), true).Length > 0) {
defaultUseGravity = type.GetCustomAttributes(typeof(DefaultUseGravity), true)[0] as DefaultUseGravity;
}
s_DefaultUseGravity.Add(type, defaultUseGravity);
return defaultUseGravity;
}
/// <summary>
/// Returns the DefaultUseRootMotionPosition of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultUseRootMotionPosition of the specified ability type. Can be null.</returns>
private static DefaultUseRootMotionPosition GetDefaultUseRootMotionPosition(Type type)
{
DefaultUseRootMotionPosition defaultUseRootMotionPosition;
if (s_DefaultUseRootMotionPosition.TryGetValue(type, out defaultUseRootMotionPosition)) {
return defaultUseRootMotionPosition;
}
if (type.GetCustomAttributes(typeof(DefaultUseRootMotionPosition), true).Length > 0) {
defaultUseRootMotionPosition = type.GetCustomAttributes(typeof(DefaultUseRootMotionPosition), true)[0] as DefaultUseRootMotionPosition;
}
s_DefaultUseRootMotionPosition.Add(type, defaultUseRootMotionPosition);
return defaultUseRootMotionPosition;
}
/// <summary>
/// Returns the DefaultUseRootMotionRotation of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultUseRootMotionRotation of the specified ability type. Can be null.</returns>
private static DefaultUseRootMotionRotation GetDefaultUseRootMotionRotation(Type type)
{
DefaultUseRootMotionRotation defaultUseRootMotionRotation;
if (s_DefaultUseRootMotionRotation.TryGetValue(type, out defaultUseRootMotionRotation)) {
return defaultUseRootMotionRotation;
}
if (type.GetCustomAttributes(typeof(DefaultUseRootMotionRotation), true).Length > 0) {
defaultUseRootMotionRotation = type.GetCustomAttributes(typeof(DefaultUseRootMotionRotation), true)[0] as DefaultUseRootMotionRotation;
}
s_DefaultUseRootMotionRotation.Add(type, defaultUseRootMotionRotation);
return defaultUseRootMotionRotation;
}
/// <summary>
/// Returns the DefaultDetectHorizontalCollisions of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultDetectHorizontalCollisions of the specified ability type. Can be null.</returns>
private static DefaultDetectHorizontalCollisions GetDefaultDetectHorizontalCollisions(Type type)
{
DefaultDetectHorizontalCollisions defaultDetectHorizontalCollisions;
if (s_DefaultDetectHorizontalCollisions.TryGetValue(type, out defaultDetectHorizontalCollisions)) {
return defaultDetectHorizontalCollisions;
}
if (type.GetCustomAttributes(typeof(DefaultDetectHorizontalCollisions), true).Length > 0) {
defaultDetectHorizontalCollisions = type.GetCustomAttributes(typeof(DefaultDetectHorizontalCollisions), true)[0] as DefaultDetectHorizontalCollisions;
}
s_DefaultDetectHorizontalCollisions.Add(type, defaultDetectHorizontalCollisions);
return defaultDetectHorizontalCollisions;
}
/// <summary>
/// Returns the DefaultDetectVerticalCollisions of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultDetectVerticalCollisions of the specified ability type. Can be null.</returns>
private static DefaultDetectVerticalCollisions GetDefaultDetectVerticalCollisions(Type type)
{
DefaultDetectVerticalCollisions defaultDetectVerticalCollisions;
if (s_DefaultDetectVerticalCollisions.TryGetValue(type, out defaultDetectVerticalCollisions)) {
return defaultDetectVerticalCollisions;
}
if (type.GetCustomAttributes(typeof(DefaultDetectVerticalCollisions), true).Length > 0) {
defaultDetectVerticalCollisions = type.GetCustomAttributes(typeof(DefaultDetectVerticalCollisions), true)[0] as DefaultDetectVerticalCollisions;
}
s_DefaultDetectVerticalCollisions.Add(type, defaultDetectVerticalCollisions);
return defaultDetectVerticalCollisions;
}
/// <summary>
/// Returns the DefaultObjectDetection of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultObjectDetection of the specified ability type. Can be null.</returns>
private static DefaultObjectDetection GetDefaultObjectDetection(Type type)
{
DefaultObjectDetection defaultObjectDetection;
if (s_DefaultObjectDetection.TryGetValue(type, out defaultObjectDetection)) {
return defaultObjectDetection;
}
if (type.GetCustomAttributes(typeof(DefaultObjectDetection), true).Length > 0) {
defaultObjectDetection = type.GetCustomAttributes(typeof(DefaultObjectDetection), true)[0] as DefaultObjectDetection;
}
s_DefaultObjectDetection.Add(type, defaultObjectDetection);
return defaultObjectDetection;
}
/// <summary>
/// Returns the DefaultUseLookDirection of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultUseLookDirection of the specified ability type. Can be null.</returns>
private static DefaultUseLookDirection GetDefaultUseLookDirection(Type type)
{
DefaultUseLookDirection defaultUseLookDirection;
if (s_DefaultUseLookDirection.TryGetValue(type, out defaultUseLookDirection)) {
return defaultUseLookDirection;
}
if (type.GetCustomAttributes(typeof(DefaultUseLookDirection), true).Length > 0) {
defaultUseLookDirection = type.GetCustomAttributes(typeof(DefaultUseLookDirection), true)[0] as DefaultUseLookDirection;
}
s_DefaultUseLookDirection.Add(type, defaultUseLookDirection);
return defaultUseLookDirection;
}
/// <summary>
/// Returns the DefaultCastOffset of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultCastOffset of the specified ability type. Can be null.</returns>
private static DefaultCastOffset GetDefaultCastOffset(Type type)
{
DefaultCastOffset defaultCastOffset;
if (s_DefaultCastOffset.TryGetValue(type, out defaultCastOffset)) {
return defaultCastOffset;
}
if (type.GetCustomAttributes(typeof(DefaultCastOffset), true).Length > 0) {
defaultCastOffset = type.GetCustomAttributes(typeof(DefaultCastOffset), true)[0] as DefaultCastOffset;
}
s_DefaultCastOffset.Add(type, defaultCastOffset);
return defaultCastOffset;
}
/// <summary>
/// Returns the DefaultEquippedSlots of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultEquippedSlots of the specified ability type. Can be null.</returns>
private static DefaultEquippedSlots GetDefaultEquippedSlots(Type type)
{
DefaultEquippedSlots defaultEquippedSlots;
if (s_DefaultEquippedSlots.TryGetValue(type, out defaultEquippedSlots)) {
return defaultEquippedSlots;
}
if (type.GetCustomAttributes(typeof(DefaultEquippedSlots), true).Length > 0) {
defaultEquippedSlots = type.GetCustomAttributes(typeof(DefaultEquippedSlots), true)[0] as DefaultEquippedSlots;
}
s_DefaultEquippedSlots.Add(type, defaultEquippedSlots);
return defaultEquippedSlots;
}
/// <summary>
/// Returns the DefaultReequipSlots of the specified ability type.
/// </summary>
/// <param name="type">The type of ability.</param>
/// <returns>The DefaultReequipSlots of the specified ability type. Can be null.</returns>
private static DefaultReequipSlots GetDefaultReequipSlots(Type type)
{
DefaultReequipSlots defaultReequipSlots;
if (s_DefaultReequipSlots.TryGetValue(type, out defaultReequipSlots)) {
return defaultReequipSlots;
}
if (type.GetCustomAttributes(typeof(DefaultReequipSlots), true).Length > 0) {
defaultReequipSlots = type.GetCustomAttributes(typeof(DefaultReequipSlots), true)[0] as DefaultReequipSlots;
}
s_DefaultReequipSlots.Add(type, defaultReequipSlots);
return defaultReequipSlots;
}
/// <summary>
/// Returns the AddState of the specified ability type.
/// </summary>
/// <param name="type">The view type.</param>
/// <returns>The AddState of the specified ability type. Can be null.</returns>
private static AddState[] GetAddStates(Type type)
{
AddState[] addStates;
if (s_AddStates.TryGetValue(type, out addStates)) {
return addStates;
}
if (type.GetCustomAttributes(typeof(AddState), true).Length > 0) {
addStates = type.GetCustomAttributes(typeof(AddState), true) as AddState[];
}
s_AddStates.Add(type, addStates);
return addStates;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 16526568bd0b93842984441fd97bc59f
timeCreated: 1513110789
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,726 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility.Builders
{
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;
using Opsive.UltimateCharacterController.Character.Identifiers;
using Opsive.UltimateCharacterController.Character.MovementTypes;
using Opsive.UltimateCharacterController.Game;
using Opsive.UltimateCharacterController.Inventory;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Allows for the Ultimate Character Controller components to be added/removed at runtime.
/// </summary>
public static class CharacterBuilder
{
private const string c_MovingStateGUID = "527d884c54f1a4b4a82fed73411305a8";
/// <summary>
/// Adds the essnetial components to the specified character and sets the MovementType.
/// </summary>
/// <param name="character">The GameObject of the character.</param>
/// <param name="addAnimator">Should the animator components be added?</param>
/// <param name="animatorController">A reference to the animator controller.</param>
/// <param name="firstPersonMovementType">The first person MovementType that should be added.</param>
/// <param name="thirdPersonMovementType">The third person MovementType that should be added.</param>
/// <param name="startFirstPersonPerspective">Should the character start in a first person perspective?</param>
/// <param name="firstPersonHiddenObjects">The objects that should be hidden in first person view.</param>
/// <param name="invisibleShadowCasterMaterial">The shadow caster material applied to the invisible first person objects.</param>
/// <param name="aiAgent">Is the character an AI agent?</param>
public static void BuildCharacter(GameObject character, bool addAnimator, RuntimeAnimatorController animatorController, string firstPersonMovementType, string thirdPersonMovementType, bool startFirstPersonPerspective,
GameObject[] firstPersonHiddenObjects, Material invisibleShadowCasterMaterial, bool aiAgent)
{
// Determine if the ThirdPersonObject component should be added or the invisible object renderer should be directly set to the invisible shadow caster.
if (firstPersonHiddenObjects != null) {
for (int i = 0; i < firstPersonHiddenObjects.Length; ++i) {
if (firstPersonHiddenObjects[i] == null) {
continue;
}
if (string.IsNullOrEmpty(thirdPersonMovementType)) {
var renderers = firstPersonHiddenObjects[i].GetComponents<Renderer>();
for (int j = 0; j < renderers.Length; ++j) {
var materials = renderers[j].sharedMaterials;
for (int k = 0; k < materials.Length; ++k) {
materials[k] = invisibleShadowCasterMaterial;
}
renderers[j].sharedMaterials = materials;
}
}
firstPersonHiddenObjects[i].AddComponent<ThirdPersonObject>();
}
}
AddEssentials(character, addAnimator, animatorController, !string.IsNullOrEmpty(firstPersonMovementType) && !string.IsNullOrEmpty(thirdPersonMovementType), invisibleShadowCasterMaterial, aiAgent);
// The last added MovementType is starting movement type.
if (startFirstPersonPerspective) {
if (!string.IsNullOrEmpty(thirdPersonMovementType)) {
AddMovementType(character, thirdPersonMovementType);
}
if (!string.IsNullOrEmpty(firstPersonMovementType)) {
AddMovementType(character, firstPersonMovementType);
}
} else {
if (!string.IsNullOrEmpty(firstPersonMovementType)) {
AddMovementType(character, firstPersonMovementType);
}
if (!string.IsNullOrEmpty(thirdPersonMovementType)) {
AddMovementType(character, thirdPersonMovementType);
}
}
}
/// <summary>
/// Adds the Ultimate Character Controller essential components to the specified character.
/// </summary>
/// <param name="character">The character to add the components to.</param>
/// <param name="addAnimator">Should the animator components be added?</param>
/// <param name="animatorController">A reference to the animator controller.</param>
/// <param name="addPerspectiveMonitor">Should the perspective monitor be added?</param>
/// <param name="invisibleShadowCasterMaterial">The shadow caster material applied to the invisible first person objects.</param>
/// <param name="aiAgent">Is the character an AI agent?</param>
public static void AddEssentials(GameObject character, bool addAnimator, RuntimeAnimatorController animatorController, bool addPerspectiveMonitor, Material invisibleShadowCasterMaterial, bool aiAgent)
{
if (!aiAgent) {
character.tag = "Player";
}
character.layer = LayerManager.Character;
if (character.GetComponent<CharacterLayerManager>() == null) {
character.AddComponent<CharacterLayerManager>();
}
var rigidbody = character.GetComponent<Rigidbody>();
if (rigidbody == null) {
rigidbody = character.AddComponent<Rigidbody>();
}
rigidbody.useGravity = false;
rigidbody.isKinematic = true;
rigidbody.constraints = RigidbodyConstraints.FreezeAll;
GameObject collider = null;
var colliderIdentifier = character.GetComponent<CharacterColliderBaseIdentifier>();
if (colliderIdentifier == null) {
var colliders = new GameObject("Colliders");
colliders.layer = LayerManager.Character;
colliders.transform.SetParentOrigin(character.transform);
collider = new GameObject("CapsuleCollider");
collider.layer = LayerManager.Character;
collider.transform.SetParentOrigin(colliders.transform);
var capsuleCollider = collider.AddComponent<CapsuleCollider>();
capsuleCollider.center = new Vector3(0, 1, 0);
capsuleCollider.height = 2;
capsuleCollider.radius = 0.4f;
}
if (addAnimator) {
AddAnimator(character, animatorController, aiAgent);
}
if (character.GetComponent<UltimateCharacterLocomotion>() == null) {
#if UNITY_EDITOR
var characterLocomotion = character.AddComponent<UltimateCharacterLocomotion>();
if (!Application.isPlaying) {
// The Moving state should automatically be added.
var presetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(c_MovingStateGUID);
if (!string.IsNullOrEmpty(presetPath)) {
var preset = UnityEditor.AssetDatabase.LoadAssetAtPath(presetPath, typeof(StateSystem.PersistablePreset)) as StateSystem.PersistablePreset;
if (preset != null) {
var states = characterLocomotion.States;
System.Array.Resize(ref states, states.Length + 1);
// Default must always be at the end.
states[states.Length - 1] = states[0];
states[states.Length - 2] = new StateSystem.State("Moving", preset, null);
characterLocomotion.States = states;
}
}
}
#else
character.AddComponent<UltimateCharacterLocomotion>();
#endif
}
if (collider != null) {
var positioner = collider.AddComponent<CapsuleColliderPositioner>();
positioner.FirstEndCapTarget = character.transform;
var animator = character.GetComponent<Animator>();
if (animator != null) {
// The CapsuleColliderPositioner should follow the character's movements.
var head = animator.GetBoneTransform(HumanBodyBones.Head);
if (head != null) {
positioner.SecondEndCapTarget = head;
positioner.RotationBone = positioner.PositionBone = animator.GetBoneTransform(HumanBodyBones.Hips);
}
}
}
if (aiAgent) {
AddAIAgent(character);
} else {
AddUnityInput(character);
if (character.GetComponent<UltimateCharacterLocomotionHandler>() == null) {
character.AddComponent<UltimateCharacterLocomotionHandler>();
}
}
#if THIRD_PERSON_CONTROLLER
if (addPerspectiveMonitor && character.GetComponent<ThirdPersonController.Character.PerspectiveMonitor>() == null) {
var perspectiveMonitor = character.AddComponent<ThirdPersonController.Character.PerspectiveMonitor>();
if (perspectiveMonitor.InvisibleMaterial == null) {
perspectiveMonitor.InvisibleMaterial = invisibleShadowCasterMaterial;
}
}
#endif
// All of the child GameObjects should be set to the SubCharacter layer to prevent any added-colliders from interferring with the locomotion.
SetRecursiveLayer(character, LayerManager.SubCharacter, LayerManager.Character);
}
/// <summary>
/// Adds the animator with the specified controller to the character.
/// </summary>
/// <param name="character">The character to add the animator to.</param>
/// <param name="animatorController">A reference to the animator controller.</param>
/// <param name="aiAgent">Is the character an AI agent?</param>
public static void AddAnimator(GameObject character, RuntimeAnimatorController animatorController, bool aiAgent)
{
Animator animator;
if ((animator = character.GetComponent<Animator>()) == null) {
animator = character.AddComponent<Animator>();
}
animator.runtimeAnimatorController = animatorController;
if (!aiAgent) {
animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
}
if (character.GetComponent<AnimatorMonitor>() == null) {
character.AddComponent<AnimatorMonitor>();
}
}
/// <summary>
/// Removes the animator from the character.
/// </summary>
/// <param name="character">The character to remove the animator from.</param>
public static void RemoveAnimator(GameObject character)
{
var animator = character.GetComponent<Animator>();
if (animator != null) {
GameObject.DestroyImmediate(animator, true);
}
var animatorMonitor = character.GetComponent<AnimatorMonitor>();
if (animatorMonitor != null) {
GameObject.DestroyImmediate(animatorMonitor, true);
}
}
/// <summary>
/// Sets the GameObject to the specified layer. Will recursively set the children unless the child contains a component that shouldn't be set.
/// </summary>
/// <param name="gameObject">The GameObject to set.</param>
/// <param name="layer">The layer to set the GameObject to.</param>
/// <param name="characterLayer">The layer of the character. GameObjects with this layer will not be set to the specified layer.</param>
private static void SetRecursiveLayer(GameObject gameObject, int layer, int characterLayer)
{
var children = gameObject.transform.childCount;
for (int i = 0; i < gameObject.transform.childCount; ++i) {
var child = gameObject.transform.GetChild(i);
// Do not set the layer if the child is already set to the Character layer or contains the item identifier components.
if (child.gameObject.layer == characterLayer || child.GetComponent<Items.ItemPlacement>() != null) {
continue;
}
#if FIRST_PERSON_CONTROLLER
// First person objects do not need to be set.
if (child.GetComponent<FirstPersonController.Character.FirstPersonObjects>() != null) {
continue;
}
#endif
// Set the layer.
child.gameObject.layer = layer;
SetRecursiveLayer(child.gameObject, layer, characterLayer);
}
}
/// <summary>
/// Removes the Ultimate Character Controller essential components from the specified character.
/// </summary>
/// <param name="character">The character to remove the components from.</param>
public static void RemoveEssentials(GameObject character)
{
var rigidbody = character.GetComponent<Rigidbody>();
if (rigidbody != null) {
GameObject.DestroyImmediate(rigidbody, true);
}
var collider = character.GetComponent<CharacterColliderBaseIdentifier>();
if (collider != null) {
GameObject.DestroyImmediate(collider, true);
}
var ultimateCharacterLocomotion = character.GetComponent<UltimateCharacterLocomotion>();
if (ultimateCharacterLocomotion != null) {
GameObject.DestroyImmediate(ultimateCharacterLocomotion, true);
}
var ultimateCharacterLocomotionHandler = character.GetComponent<UltimateCharacterLocomotionHandler>();
if (ultimateCharacterLocomotionHandler != null) {
GameObject.DestroyImmediate(ultimateCharacterLocomotionHandler, true);
}
var localLookSource = character.GetComponent<LocalLookSource>();
if (localLookSource != null) {
GameObject.DestroyImmediate(localLookSource, true);
}
var layerManager = character.GetComponent<CharacterLayerManager>();
if (layerManager != null) {
GameObject.DestroyImmediate(layerManager, true);
}
#if THIRD_PERSON_CONTROLLER
var perspectiveMonitor = character.GetComponent<ThirdPersonController.Character.PerspectiveMonitor>();
if (perspectiveMonitor != null) {
GameObject.DestroyImmediate(perspectiveMonitor, true);
}
#endif
}
/// <summary>
/// Adds the specified MovementType to the character.
/// </summary>
/// <param name="character">The character to add the MovementType to.</param>
/// <param name="movementType">The MovementType to add.</param>
public static void AddMovementType(GameObject character, string movementType)
{
var ultimateCharacterLocomotion = character.GetComponent<UltimateCharacterLocomotion>();
if (ultimateCharacterLocomotion != null) {
// Don't allow duplicate MovementTypes.
var type = System.Type.GetType(movementType);
ultimateCharacterLocomotion.DeserializeMovementTypes();
var movementTypes = ultimateCharacterLocomotion.MovementTypes;
var add = true;
if (movementTypes != null) {
for (int i = 0; i < movementTypes.Length; ++i) {
if (movementTypes[i].GetType() == type) {
add = false;
}
}
}
if (add) {
var movementTypesList = new List<MovementType>();
if (movementTypes != null) {
movementTypesList.AddRange(movementTypes);
}
var movementTypeObj = System.Activator.CreateInstance(type) as MovementType;
movementTypesList.Add(movementTypeObj);
ultimateCharacterLocomotion.MovementTypes = movementTypesList.ToArray();
ultimateCharacterLocomotion.MovementTypeData = Shared.Utility.Serialization.Serialize<MovementType>(movementTypesList);
// If the character has already been initialized then the movement type should be initialized.
if (Application.isPlaying) {
movementTypeObj.Initialize(ultimateCharacterLocomotion);
movementTypeObj.Awake();
}
}
// Set the added movement type as the default.
ultimateCharacterLocomotion.SetMovementType(type);
}
}
/// <summary>
/// Adds the non-essential Ultimate Character Controller components to the character.
/// </summary>
/// <param name="character">The character to add the components to.</param>
/// <param name="aiAgent">Is the character an AI agent?</param>
/// <param name="addItems">Should the item components be added?</param>
/// <param name="itemCollection">A reference to the ItemCollection component.</param>
/// <param name="firstPersonItems">Does the character support first person items?</param>
/// <param name="addHealth">Should the health components be added?</param>
/// <param name="addUnityIK">Should the CharacterIK component be added?</param>
/// <param name="addFootEffects">Should the CharacterFootEffects component be added?</param>
/// <param name="addStandardAbilities">Should the standard abilities be added?</param>
/// <param name="addNavMeshAgent">Should the NavMeshAgent component be added?</param>
public static void BuildCharacterComponents(GameObject character, bool aiAgent, bool addItems,
ItemCollection itemCollection, bool firstPersonItems, bool addHealth, bool addUnityIK, bool addFootEffects, bool addStandardAbilities, bool addNavMeshAgent)
{
if (addItems) {
AddItemSupport(character, itemCollection, aiAgent, firstPersonItems);
}
if (addHealth) {
AddHealth(character);
}
if (addUnityIK) {
AddUnityIK(character);
}
if (addFootEffects) {
AddFootEffects(character);
}
if (addStandardAbilities) {
// Add the Jump, Fall, Speed Change, and Height Change abilities.
var characterLocomotion = character.GetComponent<UltimateCharacterLocomotion>();
var jump = AbilityBuilder.AddAbility(characterLocomotion, typeof(Character.Abilities.Jump));
if (characterLocomotion.GetComponent<Animator>() == null) {
(jump as Jump).JumpEvent = new AnimationEventTrigger(false, 0);
AbilityBuilder.SerializeAbilities(characterLocomotion);
}
AbilityBuilder.AddAbility(characterLocomotion, typeof(Character.Abilities.Fall));
AbilityBuilder.AddAbility(characterLocomotion, typeof(Character.Abilities.MoveTowards));
AbilityBuilder.AddAbility(characterLocomotion, typeof(Character.Abilities.SpeedChange));
AbilityBuilder.AddAbility(characterLocomotion, typeof(Character.Abilities.HeightChange));
// The abilities should not use an input related start type.
if (aiAgent) {
var abilities = characterLocomotion.GetAbilities<Character.Abilities.Ability>();
for (int i = 0; i < abilities.Length; ++i) {
if (abilities[i].StartType != Character.Abilities.Ability.AbilityStartType.Automatic &&
abilities[i].StartType != Character.Abilities.Ability.AbilityStartType.Manual) {
abilities[i].StartType = Character.Abilities.Ability.AbilityStartType.Manual;
}
if (abilities[i].StopType != Character.Abilities.Ability.AbilityStopType.Automatic &&
abilities[i].StopType != Character.Abilities.Ability.AbilityStopType.Manual) {
abilities[i].StopType = Character.Abilities.Ability.AbilityStopType.Manual;
}
if (abilities[i] is Character.Abilities.Items.Use) {
abilities[i].StopType = Character.Abilities.Ability.AbilityStopType.Manual;
}
}
AbilityBuilder.SerializeAbilities(characterLocomotion);
}
}
if (addNavMeshAgent) {
var characterLocomotion = character.GetComponent<UltimateCharacterLocomotion>();
var abilities = characterLocomotion.Abilities;
var index = abilities != null ? abilities.Length : 0;
if (abilities != null) {
for (int i = 0; i < abilities.Length; ++i) {
if (abilities[i] is Character.Abilities.SpeedChange) {
index = i;
break;
}
}
}
// The ability should be positioned before the SpeedChange ability.
AbilityBuilder.AddAbility(characterLocomotion, typeof(Character.Abilities.AI.NavMeshAgentMovement), index);
var navMeshAgent = character.GetComponent<UnityEngine.AI.NavMeshAgent>();
if (navMeshAgent != null) {
navMeshAgent.stoppingDistance = 0.1f;
}
}
if (addItems) {
// Add the Equip, Aim, Use, and Reload item abilities.
var characterLocomotion = character.GetComponent<UltimateCharacterLocomotion>();
#if ULTIMATE_CHARACTER_CONTROLLER_SHOOTER
AbilityBuilder.AddItemAbility(characterLocomotion, typeof(Character.Abilities.Items.Reload));
#endif
AbilityBuilder.AddItemAbility(characterLocomotion, typeof(Character.Abilities.Items.Use));
AbilityBuilder.AddItemAbility(characterLocomotion, typeof(Character.Abilities.Items.EquipUnequip));
AbilityBuilder.AddItemAbility(characterLocomotion, typeof(Character.Abilities.Items.ToggleEquip));
AbilityBuilder.AddItemAbility(characterLocomotion, typeof(Character.Abilities.Items.EquipNext));
AbilityBuilder.AddItemAbility(characterLocomotion, typeof(Character.Abilities.Items.EquipPrevious));
AbilityBuilder.AddItemAbility(characterLocomotion, typeof(Character.Abilities.Items.EquipScroll));
AbilityBuilder.AddItemAbility(characterLocomotion, typeof(Character.Abilities.Items.Aim));
// The buttons should not use an input related start type.
if (aiAgent) {
var itemAbilities = characterLocomotion.GetAbilities<Character.Abilities.Items.ItemAbility>();
for (int i = 0; i < itemAbilities.Length; ++i) {
if (itemAbilities[i].StartType != Character.Abilities.Ability.AbilityStartType.Automatic &&
itemAbilities[i].StartType != Character.Abilities.Ability.AbilityStartType.Manual) {
itemAbilities[i].StartType = Character.Abilities.Ability.AbilityStartType.Manual;
}
if (itemAbilities[i].StopType != Character.Abilities.Ability.AbilityStopType.Automatic &&
itemAbilities[i].StopType != Character.Abilities.Ability.AbilityStopType.Manual) {
itemAbilities[i].StopType = Character.Abilities.Ability.AbilityStopType.Manual;
}
}
AbilityBuilder.SerializeItemAbilities(characterLocomotion);
}
// The ItemEquipVerifier needs to be added after the item abilities.
AbilityBuilder.AddAbility(characterLocomotion, typeof(Character.Abilities.ItemEquipVerifier));
AbilityBuilder.SerializeAbilities(characterLocomotion);
}
}
/// <summary>
/// Adds the ai agent components to the character.
/// </summary>
/// <param name="character">The character to add the ai agent components to.</param>
public static void AddAIAgent(GameObject character)
{
if (character.GetComponent<LocalLookSource>() == null) {
character.AddComponent<LocalLookSource>();
}
var locomotionHandler = character.GetComponent<UltimateCharacterLocomotionHandler>();
if (locomotionHandler != null) {
GameObject.DestroyImmediate(locomotionHandler, true);
}
var itemHandler = character.GetComponent<ItemHandler>();
if (itemHandler != null) {
GameObject.DestroyImmediate(itemHandler, true);
}
RemoveUnityInput(character);
}
/// <summary>
/// Removes the ai agent components from the character.
/// </summary>
/// <param name="character">The character to remove the ai agent components to.</param>
public static void RemoveAIAgent(GameObject character)
{
var localLookSource = character.GetComponent<LocalLookSource>();
if (localLookSource != null) {
GameObject.DestroyImmediate(localLookSource, true);
}
if (character.GetComponent<UltimateCharacterLocomotionHandler>() == null) {
character.AddComponent<UltimateCharacterLocomotionHandler>();
}
if (character.GetComponent<ItemHandler>() == null) {
character.AddComponent<ItemHandler>();
}
AddUnityInput(character);
AbilityBuilder.RemoveAbility<Character.Abilities.AI.NavMeshAgentMovement>(character.GetComponent<UltimateCharacterLocomotion>());
var navMeshAgent = character.GetComponent<UnityEngine.AI.NavMeshAgent>();
if (navMeshAgent != null) {
GameObject.DestroyImmediate(navMeshAgent, true);
}
}
/// <summary>
/// Adds the UnityInput component to the character.
/// </summary>
/// <param name="character">The character to add the UnityInput component to.</param>
public static void AddUnityInput(GameObject character)
{
if (character.GetComponent<UltimateCharacterController.Input.UnityInput>() == null) {
character.AddComponent<UltimateCharacterController.Input.UnityInput>();
}
}
/// <summary>
/// Removes the UnityInput component from the character.
/// </summary>
/// <param name="character">The character to remove the UnityInput component from.</param>
public static void RemoveUnityInput(GameObject character)
{
var unityInput = character.GetComponent<UltimateCharacterController.Input.UnityInput>();
if (unityInput != null) {
GameObject.DestroyImmediate(unityInput, true);
}
}
/// <summary>
/// Adds support for items to the character.
/// </summary>
/// <param name="character">The character to add support for items to.</param>
/// <param name="itemCollection">A reference to the inventory's ItemCollection.</param>
/// <param name="aiAgent">Is the character an AI agent?</param>
/// <param name="firstPersonItems">Does the character support first person items?</param>
public static void AddItemSupport(GameObject character, ItemCollection itemCollection, bool aiAgent, bool firstPersonItems)
{
// Even if the character doesn't have an animator the items may make use of one.
if (character.GetComponent<AnimatorMonitor>() == null) {
character.AddComponent<AnimatorMonitor>();
}
if (character.GetComponentInChildren<Items.ItemPlacement>() == null) {
var items = new GameObject("Items");
items.transform.parent = character.transform;
items.AddComponent<Items.ItemPlacement>();
}
var animator = character.GetComponent<Animator>();
if (animator != null) {
var head = animator.GetBoneTransform(HumanBodyBones.Head);
if (head != null) {
var leftHand = animator.GetBoneTransform(HumanBodyBones.LeftHand);
var rightHand = animator.GetBoneTransform(HumanBodyBones.RightHand);
if (leftHand != null && rightHand != null) {
if (leftHand.GetComponentInChildren<Items.ItemSlot>() == null) {
var items = new GameObject("Items");
items.transform.SetParentOrigin(leftHand.transform);
var itemSlot = items.AddComponent<Items.ItemSlot>();
itemSlot.ID = 1;
}
if (rightHand.GetComponentInChildren<Items.ItemSlot>() == null) {
var items = new GameObject("Items");
items.transform.SetParentOrigin(rightHand.transform);
items.AddComponent<Items.ItemSlot>();
}
}
}
}
// Items use the inventory for being equip/unequip.
if (character.GetComponent<Inventory>() == null) {
character.AddComponent<Inventory>();
}
#if FIRST_PERSON_CONTROLLER
if (firstPersonItems && character.GetComponentInChildren<FirstPersonController.Character.FirstPersonObjects>() == null) {
var firstPersonObjects = new GameObject("First Person Objects");
firstPersonObjects.transform.parent = character.transform;
firstPersonObjects.AddComponent<FirstPersonController.Character.FirstPersonObjects>();
}
#endif
ItemSetManager itemSetManager;
if ((itemSetManager = character.GetComponent<ItemSetManager>()) == null) {
itemSetManager = character.AddComponent<ItemSetManager>();
}
itemSetManager.ItemCollection = itemCollection;
if (!aiAgent && character.GetComponent<ItemHandler>() == null) {
character.AddComponent<ItemHandler>();
}
}
/// <summary>
/// Removes support for items from the character.
/// </summary>
/// <param name="character">The character to remove support for the items from.</param>
public static void RemoveItemSupport(GameObject character)
{
var animatorMonitor = character.GetComponent<ItemHandler>();
if (animatorMonitor != null && character.GetComponent<Animator>() == null) {
character.AddComponent<Animator>();
}
var itemHandler = character.GetComponent<ItemHandler>();
if (itemHandler != null) {
GameObject.DestroyImmediate(itemHandler, true);
}
var itemPlacement = character.GetComponentInChildren<Items.ItemPlacement>();
if (itemPlacement != null) {
GameObject.DestroyImmediate(itemPlacement.gameObject, true);
}
#if FIRST_PERSON_CONTROLLER
var firstPersonObjects = character.GetComponentInChildren<FirstPersonController.Character.FirstPersonObjects>();
if (firstPersonObjects != null) {
GameObject.DestroyImmediate(firstPersonObjects, true);
}
#endif
var itemSlots = character.GetComponentsInChildren<Items.ItemSlot>();
if (itemSlots != null && itemSlots.Length > 0) {
for (int i = itemSlots.Length - 1; i >= 0; --i) {
GameObject.DestroyImmediate(itemSlots[i].gameObject, true);
}
}
var inventory = character.GetComponent<Inventory>();
if (inventory != null) {
GameObject.DestroyImmediate(inventory, true);
}
var itemSetManager = character.GetComponent<ItemSetManager>();
if (itemSetManager != null) {
GameObject.DestroyImmediate(itemSetManager, true);
}
}
/// <summary>
/// Adds the health components to the character.
/// </summary>
/// <param name="character">The character to add the health components to.</param>
public static void AddHealth(GameObject character)
{
if (character.GetComponent<Traits.AttributeManager>() == null) {
character.AddComponent<Traits.AttributeManager>();
}
if (character.GetComponent<Traits.CharacterHealth>() == null) {
character.AddComponent<Traits.CharacterHealth>();
}
if (character.GetComponent<Traits.CharacterRespawner>() == null) {
character.AddComponent<Traits.CharacterRespawner>();
}
}
/// <summary>
/// Removes the health components from the character.
/// </summary>
/// <param name="character">The character to remove the health components from.</param>
public static void RemoveHealth(GameObject character)
{
var health = character.GetComponent<Traits.CharacterHealth>();
if (health != null) {
GameObject.DestroyImmediate(health, true);
}
var attributeManager = character.GetComponent<Traits.AttributeManager>();
if (attributeManager != null) {
GameObject.DestroyImmediate(attributeManager, true);
}
var respawner = character.GetComponent<Traits.CharacterRespawner>();
if (respawner != null) {
GameObject.DestroyImmediate(respawner, true);
}
}
/// <summary>
/// Adds the CharacterIK component to the character.
/// </summary>
/// <param name="character">The character to add the CharacterIK component to.</param>
public static void AddUnityIK(GameObject character)
{
if (character.GetComponent<CharacterIK>() == null) {
character.AddComponent<CharacterIK>();
}
}
/// <summary>
/// Removes the CharacterIK component from the character.
/// </summary>
/// <param name="character">The character to remove the CharacterIK component from.</param>
public static void RemoveUnityIK(GameObject character)
{
var characterIK = character.GetComponent<CharacterIK>();
if (characterIK != null) {
GameObject.DestroyImmediate(characterIK, true);
}
}
/// <summary>
/// Adds the CharacterFootEffects component to the character.
/// </summary>
/// <param name="character">The character to add the CharacterFootEffects component to.</param>
public static void AddFootEffects(GameObject character)
{
if (character.GetComponent<CharacterFootEffects>() == null) {
var footEffects = character.AddComponent<CharacterFootEffects>();
footEffects.InitializeHumanoidFeet();
}
}
/// <summary>
/// Removes the CharacterFootEffects component from the character.
/// </summary>
/// <param name="character">The character to remove the CharacterFootEffects component from.</param>
public static void RemoveFootEffects(GameObject character)
{
var footEffects = character.GetComponent<CharacterFootEffects>();
if (footEffects != null) {
GameObject.DestroyImmediate(footEffects, true);
}
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: c8e62d4b86ca89c40801df9a6e4900d9
timeCreated: 1503625699
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,936 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility.Builders
{
using Opsive.Shared.Inventory;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Game;
using Opsive.UltimateCharacterController.Items;
using Opsive.UltimateCharacterController.Items.Actions;
using Opsive.UltimateCharacterController.Items.Actions.PerspectiveProperties;
using Opsive.UltimateCharacterController.Inventory;
using UnityEngine;
/// <summary>
/// Builds a new item.
/// </summary>
public class ItemBuilder
{
/// <summary>
/// The type of action to create.
/// </summary>
public enum ActionType {
ShootableWeapon, // The item uses a ShootableWeapon.
MeleeWeapon, // The item uses a MeleeWeapon.
Shield, // The item uses a Shield.
MagicItem, // The item uses a MagicItem.
ThrowableItem, // The item uses a ThrowableItem.
GrenadeItem, // The item uses a GrenadeItem.
Flashlight, // The item uses a Flashlight.
Nothing // The item doesn't have any actions.
}
/// <summary>
/// Builds the item with the specified parameters.
/// </summary>
/// <param name="name">The name of the item.</param>
/// <param name="itemDefinition">The ItemDefinition that the item uses (optional).</param>
/// <param name="animatorItemID">The ID of the item within the animator.</param>
/// <param name="character">The character that the item should be attached to (optional).</param>
/// <param name="slotID">The ID of the slot that the item is parented to.</param>
/// <param name="addToDefaultLoadout">Should the item be added to the character's default loadout?</param>
/// <param name="addFirstPersonPerspective">Should the first person perspective be added?</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonObjectAnimatorController">A reference to the animator controller added to the first person object. Can be null.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item. Can be null.</param>
/// <param name="firstPersonItemSlot">A reference to the ItemSlot to add the visible item to.</param>
/// <param name="firstPersonVisibleItemAnimatorController">A reference to the animator controller added to the first person visible item. Can be null.</param>
/// <param name="addThirdPersonPerspective">Should the third person perspective be added?</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
/// <param name="thirdPersonItemSlot">A reference to the ItemSlot to add the third person item to.</param>
/// <param name="thirdPersonObjectAnimatorController">A reference to the animator controller added to the third person object. Can be null.</param>
/// <param name="invisibleShadowCasterMaterial">A reference to the invisible shadow caster material. This is only used for first person characters.</param>
/// <param name="actionType">The type of item to create.</param>
/// <param name="actionItemDefinition">The ItemDefinition that the action uses (optional).</param>
public static GameObject BuildItem(string name, ItemDefinitionBase itemDefinition, int animatorItemID, GameObject character, int slotID, bool addToDefaultLoadout, bool addFirstPersonPerspective,
GameObject firstPersonObject, RuntimeAnimatorController firstPersonObjectAnimatorController, GameObject firstPersonVisibleItem, ItemSlot firstPersonItemSlot,
RuntimeAnimatorController firstPersonVisibleItemAnimatorController, bool addThirdPersonPerspective, GameObject thirdPersonObject, ItemSlot thirdPersonItemSlot,
RuntimeAnimatorController thirdPersonObjectAnimatorController, Material invisibleShadowCasterMaterial, ActionType actionType, ItemDefinitionBase actionItemDefinition)
{
var itemGameObject = new GameObject(name);
var itemSlotID = (character == null || (firstPersonItemSlot == null && thirdPersonItemSlot == null)) ? slotID :
(firstPersonItemSlot != null ? firstPersonItemSlot.ID : thirdPersonItemSlot.ID);
// If character is null then a prefab will be created.
if (character != null) {
// The attach to object must have an ItemPlacement component.
var itemPlacement = character.GetComponentInChildren<ItemPlacement>();
if (itemPlacement == null) {
Debug.LogError("Error: Unable to find the ItemPlacement component within " + character.name + ".");
return null;
}
// Organize the main item GameObject under the ItemPlacement GameObject.
itemGameObject.transform.SetParentOrigin(itemPlacement.transform);
// The item can automatically be added to the inventory's default loadout.
if (itemDefinition != null && addToDefaultLoadout) {
var inventory = character.GetComponent<Inventory>();
var defaultLoadout = inventory.DefaultLoadout;
if (defaultLoadout == null) {
defaultLoadout = new ItemDefinitionAmount[0];
}
var hasItemDefinition = false;
for (int i = 0; i < defaultLoadout.Length; ++i) {
// If the ItemIdentifier has already been added then a new ItemIdentifier doesn't need to be added.
if (defaultLoadout[i].ItemDefinition == itemDefinition) {
defaultLoadout[i].Amount++;
hasItemDefinition = true;
break;
}
}
if (!hasItemDefinition) {
System.Array.Resize(ref defaultLoadout, defaultLoadout.Length + 1);
defaultLoadout[defaultLoadout.Length - 1] = new ItemDefinitionAmount(itemDefinition, 1);
}
// The actionItemIdentifier should also be added.
if (actionItemDefinition != null) {
hasItemDefinition = false;
for (int i = 0; i < defaultLoadout.Length; ++i) {
// If the ItemIdentifier has already been added then a new action ItemDefinition doesn't need to be added.
if (defaultLoadout[i].ItemDefinition == actionItemDefinition) {
hasItemDefinition = true;
break;
}
}
if (!hasItemDefinition) {
System.Array.Resize(ref defaultLoadout, defaultLoadout.Length + 1);
defaultLoadout[defaultLoadout.Length - 1] = new ItemDefinitionAmount(actionItemDefinition, 100);
}
}
inventory.DefaultLoadout = defaultLoadout;
// The ItemIdentifier should be added to the ItemSetManager as well.
var itemSetManager = character.GetComponent<ItemSetManager>();
if (itemSetManager != null && itemDefinition.GetItemCategory() != null) {
itemSetManager.Initialize(false);
var index = itemSetManager.CategoryToIndex(itemDefinition.GetItemCategory());
if (index > -1) {
var category = itemSetManager.CategoryItemSets[index];
hasItemDefinition = false;
for (int j = 0; j < category.ItemSetList.Count; ++j) {
if (category.ItemSetList[j].Slots[itemSlotID] == itemDefinition) {
hasItemDefinition = true;
break;
}
}
if (!hasItemDefinition) {
category.ItemSetList.Add(new ItemSet(Mathf.Max(inventory.SlotCount, itemSlotID + 1), itemSlotID, itemDefinition, null, string.Empty));
}
}
}
}
}
var item = itemGameObject.AddComponent<Item>();
item.ItemDefinition = itemDefinition;
item.SlotID = itemSlotID;
item.AnimatorItemID = animatorItemID;
#if FIRST_PERSON_CONTROLLER
// Add the first person object.
if (addFirstPersonPerspective) {
AddFirstPersonObject(character, name, itemGameObject, ref firstPersonObject, firstPersonObjectAnimatorController, ref firstPersonVisibleItem, firstPersonItemSlot,
firstPersonVisibleItemAnimatorController);
// If the character doesn't have an animator then the item should be equipped by a timer.
if (character != null && character.GetComponent<Animator>() == null) {
item.EquipEvent.WaitForAnimationEvent = false;
}
}
#endif
// Add the third person object. The character will always have a third person object if the character has an animator.
if (addThirdPersonPerspective) {
AddThirdPersonObject(character, name, itemGameObject, ref thirdPersonObject, thirdPersonItemSlot, thirdPersonObjectAnimatorController, invisibleShadowCasterMaterial,
!addFirstPersonPerspective || firstPersonObject != null || firstPersonVisibleItem != null);
}
// Add the specified action type.
AddAction(itemGameObject, addFirstPersonPerspective, firstPersonObject, firstPersonVisibleItem, addThirdPersonPerspective, thirdPersonObject, actionType, actionItemDefinition);
return itemGameObject;
}
/// <summary>
/// Creates a GameObject as the child of the parent.
/// </summary>
/// <param name="name">The name of the GameObject.</param>
/// <param name="parent">The parent of the new GameObject.</param>
/// <returns>The Trasnform of the non duplicate GameObject.</returns>
private static Transform CreateGameObject(string name, Transform parent)
{
var gameObject = new GameObject(name);
gameObject.transform.SetParentOrigin(parent);
return gameObject.transform;
}
#if FIRST_PERSON_CONTROLLER
/// <summary>
/// Adds the first person object to the specified item.
/// </summary>
/// <param name="character">The character that the first person object is being added to.</param>
/// <param name="name">The name of the item.</param>
/// <param name="itemGameObject">A reference to the item's GameObject.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonObjectAnimatorController">A reference to the animator controller added to the first person object. Can be null.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item. Can be null.</param>
/// <param name="firstPersonItemSlot">A reference to the ItemSlot to add the visible item to.</param>
/// <param name="firstPersonVisibleItemAnimatorController">A reference to the animator controller added to the first person visible item. Can be null.</param>
public static void AddFirstPersonObject(GameObject character, string name, GameObject itemGameObject,
ref GameObject firstPersonObject, RuntimeAnimatorController firstPersonObjectAnimatorController, ref GameObject firstPersonVisibleItem, ItemSlot firstPersonItemSlot,
RuntimeAnimatorController firstPersonVisibleItemAnimatorController)
{
var parentFirstPersonObject = false;
if (firstPersonObject != null && (character == null || !firstPersonObject.transform.IsChildOf(character.transform))) {
parentFirstPersonObject = true;
var origFirstPersonPerspectiveItem = firstPersonVisibleItem;
var visibleItemName = string.Empty;
var visibleItemSearchName = string.Empty;
// The visible item is a child of the object. When the object is instantiated the new visible item should be found again.
// This is done by giving the visible item a unique name.
if (firstPersonVisibleItem != null) {
visibleItemName = firstPersonVisibleItem.name;
firstPersonVisibleItem.name += Random.value.ToString();
// Remember the path so the newly created visible item can be found again.
var parent = firstPersonVisibleItem.transform.parent;
visibleItemSearchName = firstPersonVisibleItem.name;
while (parent != firstPersonObject.transform && parent != null) {
visibleItemSearchName = parent.name + "/" + visibleItemSearchName;
parent = parent.parent;
}
}
firstPersonObject = GameObject.Instantiate(firstPersonObject);
if (character == null) {
firstPersonObject.name = "First Person " + name;
} else {
firstPersonObject.name = firstPersonObject.name.Substring(0, firstPersonObject.name.Length - 7); // Remove "(Clone)".
}
AddFirstPersonArms(character, firstPersonObject, firstPersonObjectAnimatorController);
// An ItemSlot must also be added to the base object if no visible item exists.
if (firstPersonVisibleItem == null) {
firstPersonObject.AddComponent<ItemSlot>();
}
// A new visible item would have been created.
if (firstPersonVisibleItem != null) {
var foundVisibleItem = firstPersonObject.transform.Find(visibleItemSearchName);
if (foundVisibleItem != null) {
// The newly created visible item is now the main visible item.
firstPersonVisibleItem = foundVisibleItem.gameObject;
} else {
// The visible item may not have been a child of the first person object GameObject.
firstPersonVisibleItem = GameObject.Instantiate(firstPersonVisibleItem);
// The ItemSlot reference also needs to be updated.
var itemSlots = firstPersonObject.GetComponentsInChildren<ItemSlot>();
for (int i = 0; i < itemSlots.Length; ++i) {
if (itemSlots[i].ID == firstPersonItemSlot.ID) {
firstPersonItemSlot = itemSlots[i];
break;
}
}
firstPersonVisibleItem.transform.SetParentOrigin(firstPersonItemSlot.transform);
}
origFirstPersonPerspectiveItem.name = firstPersonVisibleItem.name = visibleItemName;
}
} else if (firstPersonVisibleItem != null) {
firstPersonVisibleItem = GameObject.Instantiate(firstPersonVisibleItem);
firstPersonVisibleItem.name = (character == null ? "First Person " : "") + name;
}
var perspectiveItem = itemGameObject.AddComponent<FirstPersonController.Items.FirstPersonPerspectiveItem>();
perspectiveItem.Object = firstPersonObject;
perspectiveItem.VisibleItem = firstPersonVisibleItem;
if (firstPersonVisibleItem != null) {
if (firstPersonVisibleItem.GetComponent<AudioSource>() == null) {
var audioSource = firstPersonVisibleItem.AddComponent<AudioSource>();
audioSource.playOnAwake = false;
audioSource.spatialBlend = 1;
audioSource.maxDistance = 20;
}
}
// The visible item can use an animator.
if (firstPersonVisibleItemAnimatorController != null && firstPersonVisibleItem != null) {
Animator animator;
if ((animator = firstPersonVisibleItem.GetComponent<Animator>()) == null) {
animator = firstPersonVisibleItem.AddComponent<Animator>();
}
animator.applyRootMotion = false;
animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
animator.runtimeAnimatorController = firstPersonVisibleItemAnimatorController;
if (firstPersonVisibleItem.GetComponent<ChildAnimatorMonitor>() == null) {
firstPersonVisibleItem.AddComponent<ChildAnimatorMonitor>();
}
}
Transform parentTransform = null;
if (character != null) {
// The object should be a child of the First Person Objects GameObject.
if (firstPersonObject != null && parentFirstPersonObject) {
var firstPersonObjects = character.GetComponentInChildren<FirstPersonController.Character.FirstPersonObjects>();
if (firstPersonObjects == null) {
Debug.LogError("Error: Unable to find the FirstPersonObjects component within " + character.name + ".");
return;
} else {
parentTransform = firstPersonObjects.transform;
}
} else if (firstPersonVisibleItem != null) {
parentTransform = firstPersonItemSlot.transform;
}
} else {
// The object should be a child of the item GameObject.
parentTransform = itemGameObject.transform;
}
// Assign the transform. The object will contain the visible item if it exists.
var obj = firstPersonObject && parentFirstPersonObject ? firstPersonObject : firstPersonVisibleItem;
if (obj != null) {
obj.transform.SetParentOrigin(parentTransform);
// The item's object should be on the first person overlay layer so it'll render over all other objects.
obj.transform.SetLayerRecursively(LayerManager.Overlay);
} else if (firstPersonVisibleItem != null) {
firstPersonVisibleItem.transform.SetLayerRecursively(LayerManager.Overlay);
}
// Add any properties for actions which have already been added.
AddPropertiesToActions(itemGameObject, firstPersonObject, firstPersonVisibleItem, null);
}
/// <summary>
/// Adds the FirstPersonBaseObject to the arms.
/// </summary>
/// <param name="character">The character that contains the FirstPersonObject.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonObjectAnimatorController">A reference to the animator controller added to the first person object. Can be null.</param>
public static void AddFirstPersonArms(GameObject character, GameObject firstPersonObject, RuntimeAnimatorController firstPersonObjectAnimatorController)
{
var maxID = -1;
if (character != null && firstPersonObject.GetComponent<FirstPersonController.Character.Identifiers.FirstPersonBaseObject>() == null) {
// The base object ID must be unique.
var baseObjects = character.GetComponentsInChildren<FirstPersonController.Character.Identifiers.FirstPersonBaseObject>();
for (int i = 0; i < baseObjects.Length; ++i) {
if (baseObjects[i].ID > maxID) {
maxID = baseObjects[i].ID;
}
}
}
var baseObject = firstPersonObject.AddComponent<FirstPersonController.Character.Identifiers.FirstPersonBaseObject>();
baseObject.ID = maxID + 1;
firstPersonObject.transform.SetLayerRecursively(LayerManager.Overlay);
if (firstPersonObjectAnimatorController != null) {
Animator animator;
if ((animator = firstPersonObject.GetComponent<Animator>()) == null) {
animator = firstPersonObject.AddComponent<Animator>();
}
animator.applyRootMotion = false;
animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
animator.runtimeAnimatorController = firstPersonObjectAnimatorController;
if (firstPersonObject.GetComponent<ChildAnimatorMonitor>() == null) {
firstPersonObject.AddComponent<ChildAnimatorMonitor>();
}
}
}
/// <summary>
/// Removes the third person item.
/// </summary>
/// <param name="firstPersonPerspectiveItem">The item to remove.</param>
public static void RemoveFirstPersonObject(FirstPersonController.Items.FirstPersonPerspectiveItem firstPersonPerspectiveItem)
{
// Remove any properties which use the first person object.
var itemProperties = firstPersonPerspectiveItem.GetComponents<FirstPersonController.Items.FirstPersonItemProperties>();
for (int i = itemProperties.Length - 1; i > -1; --i) {
Object.DestroyImmediate(itemProperties[i], true);
}
if (firstPersonPerspectiveItem.VisibleItem != null) {
Object.DestroyImmediate(firstPersonPerspectiveItem.VisibleItem, true);
}
Object.DestroyImmediate(firstPersonPerspectiveItem, true);
}
#endif
/// <summary>
/// Adds the third person object to the specified item.
/// </summary>
/// <param name="character">The character that the third person object is being added to.</param>
/// <param name="name">The name of the item.</param>
/// <param name="itemGameObject">A reference to the item's GameObject.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
/// <param name="thirdPersonItemSlot">A reference to the ItemSlot to add the third person item to.</param>
/// <param name="thirdPersonObjectAnimatorController">A reference to the animator controller added to the third person object. Can be null.</param>
/// <param name="invisibleShadowCasterMaterial">A reference to the invisible shadow caster material. This is only used for first person characters.</param>
/// <param name="defaultAddThirdPersonObject">Should the ThirdPersonObject component be added to the object?</param>
public static void AddThirdPersonObject(GameObject character, string name, GameObject itemGameObject, ref GameObject thirdPersonObject, ItemSlot thirdPersonItemSlot,
RuntimeAnimatorController thirdPersonObjectAnimatorController, Material invisibleShadowCasterMaterial, bool defaultAddThirdPersonObject)
{
var visibleItem = itemGameObject.AddComponent<ThirdPersonController.Items.ThirdPersonPerspectiveItem>();
if (thirdPersonObject != null) {
thirdPersonObject = GameObject.Instantiate(thirdPersonObject);
thirdPersonObject.name = (character == null ? "Third Person " : "") + name;
visibleItem.Object = thirdPersonObject;
var addThirdPersonObject = defaultAddThirdPersonObject;
#if THIRD_PERSON_CONTROLLER
if (character != null && !addThirdPersonObject) {
var characterLocomotion = character.GetComponent<UltimateCharacterLocomotion>();
var movementTypes = characterLocomotion.GetSerializedMovementTypes();
if (movementTypes != null) {
for (int i = 0; i < movementTypes.Length; ++i) {
if (characterLocomotion.MovementTypes[i].GetType().FullName.Contains("ThirdPerson")) {
addThirdPersonObject = true;
break;
}
}
}
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
var networkInfo = character.GetComponent<Networking.INetworkInfo>();
if (networkInfo != null) {
addThirdPersonObject = true;
}
#endif
}
#else
addThirdPersonObject = false;
#endif
if (addThirdPersonObject) {
// The ThirdPersonObject component is added so the PerspectiveMonitor knows what objects should use the invisible shadow caster material.
thirdPersonObject.AddComponent<Character.Identifiers.ThirdPersonObject>();
} else {
// If the ThirdPersonObject isn't added then the renderer should be directly attached.
var renderers = thirdPersonObject.GetComponentsInChildren<Renderer>();
for (int i = 0; i < renderers.Length; ++i) {
var materials = renderers[i].sharedMaterials;
for (int j = 0; j < materials.Length; ++j) {
materials[j] = invisibleShadowCasterMaterial;
}
renderers[i].sharedMaterials = materials;
}
}
if (thirdPersonObject.GetComponent<AudioSource>() == null) {
var audioSource = thirdPersonObject.AddComponent<AudioSource>();
audioSource.playOnAwake = false;
audioSource.spatialBlend = 1;
audioSource.maxDistance = 20;
}
// Optionally add the animator.
if (thirdPersonObjectAnimatorController != null) {
Animator animator;
if ((animator = thirdPersonObject.GetComponent<Animator>()) == null) {
animator = thirdPersonObject.AddComponent<Animator>();
}
animator.applyRootMotion = false;
animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
animator.runtimeAnimatorController = thirdPersonObjectAnimatorController;
if (thirdPersonObject.GetComponent<ChildAnimatorMonitor>() == null) {
thirdPersonObject.AddComponent<ChildAnimatorMonitor>();
}
}
Transform parentTransform = null;
if (character != null) {
parentTransform = thirdPersonItemSlot.transform;
} else {
// The object should be a child of the item GameObject.
parentTransform = itemGameObject.transform;
}
// Assign the transform position and layer.
thirdPersonObject.transform.SetParentOrigin(parentTransform);
thirdPersonObject.transform.SetLayerRecursively(LayerManager.SubCharacter);
}
// Add any properties for actions which have already been added.
AddPropertiesToActions(itemGameObject, null, null, thirdPersonObject);
}
/// <summary>
/// Adds the properties to any actions already created.
/// </summary>
/// <param name="itemGameObject">A reference to the item's GameObject.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
private static void AddPropertiesToActions(GameObject itemGameObject, GameObject firstPersonObject, GameObject firstPersonVisibleItem, GameObject thirdPersonObject)
{
var actions = itemGameObject.GetComponents<ItemAction>();
for (int i = 0; i < actions.Length; ++i) {
#if ULTIMATE_CHARACTER_CONTROLLER_SHOOTER
if (actions[i] is ShootableWeapon) {
AddShootableWeaponProperties(itemGameObject, actions[i].ID, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
continue;
}
#endif
#if ULTIMATE_CHARACTER_CONTROLLER_MELEE
if (actions[i] is MeleeWeapon) {
AddMeleeWeaponProperties(itemGameObject, actions[i].ID, (firstPersonObject != null || firstPersonVisibleItem != null), firstPersonVisibleItem, thirdPersonObject != null, thirdPersonObject);
continue;
}
#endif
if (actions[i] is GrenadeItem) {
AddGrenadeItemProperties(itemGameObject, actions[i].ID, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
continue;
}
if (actions[i] is ThrowableItem) {
AddThrowableItemProperties(itemGameObject, actions[i].ID, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
continue;
}
if (actions[i] is Flashlight) {
AddFlashlightProperties(itemGameObject, actions[i].ID, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
continue;
}
}
}
/// <summary>
/// Removes the third person item.
/// </summary>
/// <param name="thirdPersonVisibleItem">The item to remove.</param>
public static void RemoveThirdPersonObject(ThirdPersonController.Items.ThirdPersonPerspectiveItem thirdPersonVisibleItem)
{
// Remove any properties which use the third person object.
var itemProperties = thirdPersonVisibleItem.GetComponents<ThirdPersonController.Items.ThirdPersonItemProperties>();
for (int i = itemProperties.Length - 1; i > -1; --i) {
Object.DestroyImmediate(itemProperties[i], true);
}
Object.DestroyImmediate(thirdPersonVisibleItem.Object, true);
Object.DestroyImmediate(thirdPersonVisibleItem, true);
}
/// <summary>
/// Adds the specified ActionType to the item.
/// </summary>
/// <param name="itemGameObject">The GameObject to add the action to.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
/// <param name="actionType">The type of action to add.</param>
/// <param name="actionItemDefinition">The ItemDefinition that the action uses (optional).</param>
public static void AddAction(GameObject itemGameObject, bool addFirstPersonPerspective, GameObject firstPersonObject, GameObject firstPersonVisibleItem,
bool addThirdPersonPerspective, GameObject thirdPersonObject, ActionType actionType, ItemDefinitionBase actionItemDefinition)
{
// The action ID must be unique.
var maxID = -1;
var actions = itemGameObject.GetComponents<ItemAction>();
for (int i = 0; i < actions.Length; ++i) {
if (actions[i].ID > maxID) {
maxID = actions[i].ID;
}
}
switch (actionType) {
#if ULTIMATE_CHARACTER_CONTROLLER_SHOOTER
case ActionType.ShootableWeapon:
var shootableWeapon = itemGameObject.AddComponent<ShootableWeapon>();
shootableWeapon.ID = maxID + 1;
shootableWeapon.ConsumableItemDefinition = actionItemDefinition;
AddShootableWeaponProperties(itemGameObject, shootableWeapon.ID, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
break;
#endif
#if ULTIMATE_CHARACTER_CONTROLLER_MELEE
case ActionType.MeleeWeapon:
var meleeWeapon = itemGameObject.AddComponent<MeleeWeapon>();
meleeWeapon.ID = maxID + 1;
meleeWeapon.FaceTarget = false;
AddMeleeWeaponProperties(itemGameObject, meleeWeapon.ID, addFirstPersonPerspective, firstPersonVisibleItem, addThirdPersonPerspective, thirdPersonObject);
break;
case ActionType.Shield:
var shield = itemGameObject.AddComponent<Shield>();
shield.ID = maxID + 1;
var shieldAttributeManager = itemGameObject.AddComponent<Traits.AttributeManager>();
shieldAttributeManager.Attributes[0].Name = "Durability"; // Rename the Health attribute to Durability.
AddShieldProperties(shield, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
// The Block ability should be added if it isn't already.
var characterLocomotion = itemGameObject.GetComponentInParent<UltimateCharacterLocomotion>();
if (characterLocomotion != null) {
var blockAbility = characterLocomotion.GetAbility<Character.Abilities.Items.Block>();
if (blockAbility == null) {
AbilityBuilder.AddAbility(characterLocomotion, typeof(Character.Abilities.Items.Block));
}
}
break;
#endif
case ActionType.MagicItem:
var magicItem = itemGameObject.AddComponent<MagicItem>();
var item = itemGameObject.GetComponent<Item>();
item.EquipEvent = new AnimationEventTrigger(false, 0);
item.UnequipEvent = new AnimationEventTrigger(false, 0);
AddMagicItemProperties(itemGameObject, magicItem.ID, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
break;
case ActionType.ThrowableItem:
var throwableItem = itemGameObject.AddComponent<ThrowableItem>();
throwableItem.ID = maxID + 1;
throwableItem.CanEquipEmptyItem = false;
AddThrowableItemProperties(itemGameObject, throwableItem.ID, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
break;
case ActionType.GrenadeItem:
var grenadeItem = itemGameObject.AddComponent<GrenadeItem>();
grenadeItem.ID = maxID + 1;
grenadeItem.CanEquipEmptyItem = false;
AddGrenadeItemProperties(itemGameObject, grenadeItem.ID, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
break;
case ActionType.Flashlight:
var flashLight = itemGameObject.AddComponent<Flashlight>();
flashLight.ID = maxID + 1;
flashLight.UseEvent = new AnimationEventTrigger(false, 0);
flashLight.UseCompleteEvent = new AnimationEventTrigger(false, 0);
var flashlightAttributeManager = itemGameObject.AddComponent<Traits.AttributeManager>();
flashlightAttributeManager.Attributes[0].Name = "Battery"; // Rename the Health attribute to Battery.
AddFlashlightProperties(itemGameObject, flashLight.ID, firstPersonObject, firstPersonVisibleItem, thirdPersonObject);
break;
}
}
#if ULTIMATE_CHARACTER_CONTROLLER_SHOOTER
/// <summary>
/// Adds the ShootableWeaponProperties to the specified GameObject.
/// </summary>
/// <param name="itemGameObject">The GameObject to add the properties to.</param>
/// <param name="actionID">The ActionID of the properties.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
private static void AddShootableWeaponProperties(GameObject itemGameObject, int actionID, GameObject firstPersonObject, GameObject firstPersonVisibleItem, GameObject thirdPersonObject)
{
#if FIRST_PERSON_SHOOTER
if (firstPersonObject != null || firstPersonVisibleItem != null) {
var parent = firstPersonVisibleItem != null ? firstPersonVisibleItem.transform : firstPersonObject.transform;
var shootableProperties = itemGameObject.AddComponent<FirstPersonController.Items.FirstPersonShootableWeaponProperties>();
// Setup the standard references.
shootableProperties.ActionID = actionID;
shootableProperties.FirePointLocation = CreateGameObject("Fire Point", parent);
shootableProperties.MuzzleFlashLocation = CreateGameObject("Muzzle Flash", parent);
shootableProperties.ShellLocation = CreateGameObject("Shell Eject Point", parent);
}
#endif
if (thirdPersonObject != null) {
var shootableProperties = itemGameObject.AddComponent<ThirdPersonController.Items.ThirdPersonShootableWeaponProperties>();
// Setup the standard references.
shootableProperties.ActionID = actionID;
shootableProperties.FirePointLocation = CreateGameObject("Fire Point", thirdPersonObject.transform);
shootableProperties.MuzzleFlashLocation = CreateGameObject("Muzzle Flash", thirdPersonObject.transform);
shootableProperties.ShellLocation = CreateGameObject("Shell Eject Point", thirdPersonObject.transform);
}
}
#endif
#if ULTIMATE_CHARACTER_CONTROLLER_MELEE
/// <summary>
/// Adds the MeleeWeaponProperties to the specified GameObject.
/// </summary>
/// <param name="itemGameObject">The GameObject to add the properties to.</param>
/// <param name="actionID">The ActionID of the properties.</param>
/// <param name="addFirstPersonPerspective">Should the first person perspective be added?</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="addThirdPersonPerspective">Should the third person perspective be added?</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
private static void AddMeleeWeaponProperties(GameObject itemGameObject, int actionID, bool addFirstPersonPerspective, GameObject firstPersonVisibleItem,
bool addThirdPersonPerspective, GameObject thirdPersonObject)
{
#if FIRST_PERSON_MELEE
if (itemGameObject) {
var meleeWeaponProperties = itemGameObject.AddComponent<FirstPersonController.Items.FirstPersonMeleeWeaponProperties>();
meleeWeaponProperties.ActionID = actionID;
if (firstPersonVisibleItem != null) {
BoxCollider boxCollider;
if ((boxCollider = firstPersonVisibleItem.GetComponent<BoxCollider>()) == null) {
boxCollider = firstPersonVisibleItem.AddComponent<BoxCollider>();
}
meleeWeaponProperties.Hitboxes = new MeleeWeapon.MeleeHitbox[] { new MeleeWeapon.MeleeHitbox(boxCollider) };
}
}
#endif
if (addThirdPersonPerspective) {
var meleeWeaponProperties = itemGameObject.AddComponent<ThirdPersonController.Items.ThirdPersonMeleeWeaponProperties>();
meleeWeaponProperties.ActionID = actionID;
if (thirdPersonObject != null) {
BoxCollider boxCollider;
if ((boxCollider = thirdPersonObject.GetComponent<BoxCollider>()) == null) {
boxCollider = thirdPersonObject.AddComponent<BoxCollider>();
}
meleeWeaponProperties.Hitboxes = new MeleeWeapon.MeleeHitbox[] { new MeleeWeapon.MeleeHitbox(boxCollider) };
}
}
}
/// <summary>
/// Adds the shield properties to the specified GameObject.
/// </summary>
/// <param name="shield">A reference to the parent Shield component.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
private static void AddShieldProperties(Shield shield, GameObject firstPersonObject, GameObject firstPersonVisibleItem, GameObject thirdPersonObject)
{
#if FIRST_PERSON_CONTROLLER
if (firstPersonObject != null || firstPersonVisibleItem != null) {
var shieldCollider = firstPersonVisibleItem.AddComponent<Objects.ItemAssist.ShieldCollider>();
shieldCollider.Shield = shield;
shieldCollider.FirstPersonPerspective = true;
if (firstPersonVisibleItem.GetComponent<BoxCollider>() == null) {
firstPersonVisibleItem.AddComponent<BoxCollider>();
}
}
#endif
if (thirdPersonObject != null) {
var shieldCollider = thirdPersonObject.AddComponent<Objects.ItemAssist.ShieldCollider>();
shieldCollider.Shield = shield;
if (thirdPersonObject.GetComponent<BoxCollider>() == null) {
thirdPersonObject.AddComponent<BoxCollider>();
}
}
}
#endif
/// <summary>
/// Adds the MagicItemProperties to the specified GameObject.
/// </summary>
/// <param name="itemGameObject">The GameObject to add the properties to.</param>
/// <param name="actionID">The ActionID of the properties.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
private static void AddMagicItemProperties(GameObject itemGameObject, int actionID, GameObject firstPersonObject, GameObject firstPersonVisibleItem, GameObject thirdPersonObject)
{
#if FIRST_PERSON_CONTROLLER
if (firstPersonObject != null || firstPersonVisibleItem != null) {
var parent = firstPersonVisibleItem != null ? firstPersonVisibleItem.transform : firstPersonObject.transform;
var magicItemProperties = itemGameObject.AddComponent<FirstPersonController.Items.FirstPersonMagicItemProperties>();
// Setup the standard references.
magicItemProperties.ActionID = actionID;
magicItemProperties.OriginLocation = CreateGameObject("Origin", parent);
}
#endif
var character = itemGameObject.GetComponentInParent<UltimateCharacterLocomotion>();
if (thirdPersonObject != null || (character != null && character.GetComponent<Animator>() != null)) {
var magicItemProperties = itemGameObject.AddComponent<ThirdPersonController.Items.ThirdPersonMagicItemProperties>();
// Setup the standard references.
magicItemProperties.ActionID = actionID;
magicItemProperties.OriginLocation = CreateGameObject("Origin", thirdPersonObject.transform);
}
}
/// <summary>
/// Adds the ThrowableItemProperties to the specified GameObject.
/// </summary>
/// <param name="itemGameObject">The GameObject to add the properties to.</param>
/// <param name="actionID">The ActionID of the properties.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
private static void AddThrowableItemProperties(GameObject itemGameObject, int actionID, GameObject firstPersonObject, GameObject firstPersonVisibleItem, GameObject thirdPersonObject)
{
#if FIRST_PERSON_CONTROLLER
if (firstPersonObject != null || firstPersonVisibleItem != null) {
var throwableProperties = itemGameObject.AddComponent<FirstPersonController.Items.FirstPersonThrowableItemProperties>();
// Setup the standard references.
throwableProperties.ActionID = actionID;
throwableProperties.ThrowLocation = throwableProperties.TrajectoryLocation = (firstPersonVisibleItem != null ? firstPersonVisibleItem : firstPersonObject).transform;
}
#endif
if (thirdPersonObject != null) {
var throwableProperties = itemGameObject.AddComponent<ThirdPersonController.Items.ThirdPersonThrowableItemProperties>();
// Setup the standard references.
throwableProperties.ActionID = actionID;
throwableProperties.ThrowLocation = throwableProperties.TrajectoryLocation = thirdPersonObject.transform;
}
// Throwable items should be completely dropped.
var item = itemGameObject.GetComponent<Item>();
item.FullInventoryDrop = true;
}
/// <summary>
/// Adds the GrenadeItemProperties to the specified GameObject.
/// </summary>
/// <param name="itemGameObject">The GameObject to add the properties to.</param>
/// <param name="actionID">The ActionID of the properties.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
private static void AddGrenadeItemProperties(GameObject itemGameObject, int actionID, GameObject firstPersonObject, GameObject firstPersonVisibleItem, GameObject thirdPersonObject)
{
#if FIRST_PERSON_CONTROLLER
if (firstPersonObject != null || firstPersonVisibleItem != null) {
var grenadeProperties = itemGameObject.AddComponent<FirstPersonController.Items.FirstPersonGrenadeItemProperties>();
// Setup the standard references.
grenadeProperties.ActionID = actionID;
grenadeProperties.ThrowLocation = grenadeProperties.TrajectoryLocation = (firstPersonVisibleItem != null ? firstPersonVisibleItem : firstPersonObject).transform;
// The Grenade component should not exist on the first person visible item.
if (firstPersonVisibleItem != null && firstPersonVisibleItem.GetComponent<Objects.Grenade>() != null) {
GameObject.DestroyImmediate(firstPersonVisibleItem.GetComponent<Objects.Grenade>(), true);
// If the grenade component exists then a collider does as well.
if (firstPersonVisibleItem.GetComponent<Collider>() != null) {
GameObject.DestroyImmediate(firstPersonVisibleItem.GetComponent<Collider>(), true);
}
}
}
#endif
if (thirdPersonObject != null) {
var grenadeProperties = itemGameObject.AddComponent<ThirdPersonController.Items.ThirdPersonGrenadeItemProperties>();
// Setup the standard references.
grenadeProperties.ActionID = actionID;
grenadeProperties.ThrowLocation = grenadeProperties.TrajectoryLocation = thirdPersonObject.transform;
// The Grenade component should not exist on the third person object.
if (thirdPersonObject.GetComponent<Objects.Grenade>() != null) {
GameObject.DestroyImmediate(thirdPersonObject.GetComponent<Objects.Grenade>(), true);
// If the grenade component exists then a collider does as well.
if (thirdPersonObject.GetComponent<Collider>() != null) {
GameObject.DestroyImmediate(thirdPersonObject.GetComponent<Collider>(), true);
}
}
}
// Grenades should be completely dropped.
var item = itemGameObject.GetComponent<Item>();
item.FullInventoryDrop = true;
}
/// <summary>
/// Adds the FlashlightProperties to the specified GameObject.
/// </summary>
/// <param name="itemGameObject">The GameObject to add the properties to.</param>
/// <param name="actionID">The ActionID of the properties.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
private static void AddFlashlightProperties(GameObject itemGameObject, int actionID, GameObject firstPersonObject, GameObject firstPersonVisibleItem, GameObject thirdPersonObject)
{
#if FIRST_PERSON_CONTROLLER
if (firstPersonObject != null || firstPersonVisibleItem != null) {
var flashlight = itemGameObject.AddComponent<FirstPersonController.Items.FirstPersonFlashlightProperties>();
// Setup the standard references.
flashlight.ActionID = actionID;
var lightGameObject = new GameObject("Light", typeof(Light));
lightGameObject.transform.SetParentOrigin((firstPersonVisibleItem != null ? firstPersonVisibleItem : firstPersonObject).transform);
flashlight.Light = lightGameObject;
}
#endif
if (thirdPersonObject != null) {
var flashlight = itemGameObject.AddComponent<ThirdPersonController.Items.ThirdPersonFlashlightProperties>();
// Setup the standard references.
flashlight.ActionID = actionID;
var lightGameObject = new GameObject("Light", typeof(Light));
lightGameObject.transform.SetParentOrigin(thirdPersonObject.transform);
flashlight.Light = lightGameObject;
}
}
/// <summary>
/// Adds the specified ActionType to the item.
/// </summary>
/// <param name="itemGameObject">The GameObject to add the action to.</param>
/// <param name="actionType">The type of action to add.</param>
/// <param name="actionItemDefinition">The ItemDefinition that the action uses (optional).</param>
public static void AddAction(GameObject itemGameObject, ActionType actionType, ItemDefinitionBase actionItemDefinition)
{
GameObject firstPersonObject = null, firstPersonVisibleItemGameObject = null, thirdPersonObject = null;
PopulatePerspectiveObjects(itemGameObject, ref firstPersonObject, ref firstPersonVisibleItemGameObject, ref thirdPersonObject);
AddAction(itemGameObject, (firstPersonObject != null || firstPersonVisibleItemGameObject != null), firstPersonObject, firstPersonVisibleItemGameObject, thirdPersonObject != null, thirdPersonObject, actionType, actionItemDefinition);
}
/// <summary>
/// Populates the first and third person objects for the specified item GameObject.
/// </summary>
/// <param name="itemGameObject">The GameObject to get the first and third person references of.</param>
/// <param name="firstPersonObject">A reference to the GameObject used in first person view.</param>
/// <param name="firstPersonVisibleItem">A reference to the visible first person item.</param>
/// <param name="thirdPersonObject">A reference to the GameObject used in third person view.</param>
private static void PopulatePerspectiveObjects(GameObject itemGameObject, ref GameObject firstPersonObject, ref GameObject firstPersonVisibleItemGameObject, ref GameObject thirdPersonObject)
{
#if FIRST_PERSON_CONTROLLER
var firstPersonVisibleItem = itemGameObject.GetComponent<FirstPersonController.Items.FirstPersonPerspectiveItem>();
if (firstPersonVisibleItem != null) {
firstPersonObject = firstPersonVisibleItem.Object;
firstPersonVisibleItemGameObject = firstPersonVisibleItem.VisibleItem;
}
#endif
var thirdPersonVisibleItem = itemGameObject.GetComponent<ThirdPersonController.Items.ThirdPersonPerspectiveItem>();
if (thirdPersonVisibleItem != null) {
thirdPersonObject = thirdPersonVisibleItem.Object;
}
}
/// <summary>
/// Removes the specified action.
/// </summary>
/// <param name="itemAction">The action to remove.</param>
public static void RemoveAction(ItemAction itemAction)
{
// Remove the matching perspective properties first so the ID can be matched.
RemovePerspectiveProperties(itemAction.gameObject, itemAction.ID);
Object.DestroyImmediate(itemAction, true);
}
/// <summary>
/// Removes the perspective properties on the item with the specified ID.
/// </summary>
/// <param name="itemGameObject">The GameObject which has the ItemPerpsectiveProperties.</param>
private static void RemovePerspectiveProperties(GameObject itemGameObject, int actionID)
{
var perspectiveProperties = itemGameObject.GetComponents<ItemPerspectiveProperties>();
for (int i = perspectiveProperties.Length - 1; i > -1; --i) {
if (perspectiveProperties[i].ActionID != actionID) {
continue;
}
#if ULTIMATE_CHARACTER_CONTROLLER_SHOOTER
var shootableWeaponPerspectiveProperties = perspectiveProperties[i] as IShootableWeaponPerspectiveProperties;
if (shootableWeaponPerspectiveProperties != null) {
var propertyTransform = shootableWeaponPerspectiveProperties.FirePointLocation;
if (propertyTransform != null) {
Object.DestroyImmediate(propertyTransform.gameObject, true);
}
propertyTransform = shootableWeaponPerspectiveProperties.MuzzleFlashLocation;
if (propertyTransform != null) {
Object.DestroyImmediate(propertyTransform.gameObject, true);
}
propertyTransform = shootableWeaponPerspectiveProperties.ShellLocation;
if (propertyTransform != null) {
Object.DestroyImmediate(propertyTransform.gameObject, true);
}
propertyTransform = shootableWeaponPerspectiveProperties.SmokeLocation;
if (propertyTransform != null) {
Object.DestroyImmediate(propertyTransform.gameObject, true);
}
}
#endif
Object.DestroyImmediate(perspectiveProperties[i], true);
}
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: c0c054c10eb2cd343bd52134acc1df50
timeCreated: 1513169106
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,157 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility.Builders
{
using Opsive.UltimateCharacterController.Camera;
using Opsive.UltimateCharacterController.Camera.ViewTypes;
using Opsive.UltimateCharacterController.StateSystem;
using System;
using System.Collections.Generic;
/// <summary>
/// Adds and serializes CameraController view types.
/// </summary>
public static class ViewTypeBuilder
{
private static Dictionary<Type, AddState[]> s_AddStates = new Dictionary<Type, AddState[]>();
/// <summary>
/// Adds the view type with the specified type.
/// </summary>
/// <param name="cameraController">The camera to add the ability to.</param>
/// <param name="viewType">The type of view type to add.</param>
/// <returns>The added view type.</returns>
public static ViewType AddViewType(CameraController cameraController, Type viewType)
{
var viewTypes = cameraController.ViewTypes;
if (viewTypes == null) {
viewTypes = new ViewType[1];
} else {
Array.Resize(ref viewTypes, viewTypes.Length + 1);
}
var viewTypeObj = Activator.CreateInstance(viewType) as ViewType;
viewTypes[viewTypes.Length - 1] = viewTypeObj;
cameraController.ViewTypes = viewTypes;
#if FIRST_PERSON_CONTROLLER
if (viewTypeObj is FirstPersonController.Camera.ViewTypes.FirstPerson) {
AddFirstPersonCamera(cameraController, viewTypeObj as FirstPersonController.Camera.ViewTypes.FirstPerson);
}
#endif
#if UNITY_EDITOR
var addStates = GetAddStates(viewType);
if (addStates != null && addStates.Length > 0) {
var states = viewTypeObj.States;
var addedStates = 0;
var stateLength = states.Length;
Array.Resize(ref states, stateLength + addStates.Length);
// Default must always be at the end.
states[states.Length - 1] = states[0];
for (int i = 0; i < addStates.Length; ++i) {
var presetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(addStates[i].PresetGUID);
if (!string.IsNullOrEmpty(presetPath)) {
var preset = UnityEditor.AssetDatabase.LoadAssetAtPath(presetPath, typeof(PersistablePreset)) as PersistablePreset;
if (preset != null) {
states[i] = new State(addStates[i].Name, preset, null);
addedStates++;
}
}
}
if (addedStates != addStates.Length) {
Array.Resize(ref states, stateLength + addedStates);
}
viewTypeObj.States = states;
}
#endif
SerializeViewTypes(cameraController);
if (!(viewTypeObj is Transition)) {
cameraController.SetViewType(viewType, false);
}
return viewTypeObj;
}
#if FIRST_PERSON_CONTROLLER
/// <summary>
/// Adds a first person camera to the view type.
/// </summary>
/// <param name="cameraController">The camera controller that contains the view type.</param>
/// <param name="viewType">The first person view type.</param>
public static void AddFirstPersonCamera(CameraController cameraController, FirstPersonController.Camera.ViewTypes.FirstPerson viewType)
{
// A first person camera must be added to the first peron view types.
cameraController.DeserializeViewTypes();
var viewTypes = cameraController.ViewTypes;
UnityEngine.Camera firstPersonCamera = null;
FirstPersonController.Camera.ViewTypes.FirstPerson firstPersonViewType;
for (int i = 0; i < viewTypes.Length; ++i) {
if ((firstPersonViewType = viewTypes[i] as FirstPersonController.Camera.ViewTypes.FirstPerson) != null &&
firstPersonViewType.FirstPersonCamera != null) {
firstPersonCamera = firstPersonViewType.FirstPersonCamera;
break;
}
}
// If the camera is null then a new first person camera should be created.
if (firstPersonCamera == null) {
UnityEngine.Transform firstPersonCameraTransform;
if ((firstPersonCameraTransform = cameraController.transform.Find("First Person Camera")) != null) {
firstPersonCamera = firstPersonCameraTransform.GetComponent<UnityEngine.Camera>();
}
if (firstPersonCamera == null) {
var cameraGameObject = new UnityEngine.GameObject("First Person Camera");
cameraGameObject.transform.SetParentOrigin(cameraController.transform);
firstPersonCamera = cameraGameObject.AddComponent<UnityEngine.Camera>();
firstPersonCamera.clearFlags = UnityEngine.CameraClearFlags.Depth;
firstPersonCamera.fieldOfView = 60f;
firstPersonCamera.nearClipPlane = 0.01f;
firstPersonCamera.depth = 0;
firstPersonCamera.renderingPath = cameraController.GetComponent<UnityEngine.Camera>().renderingPath;
}
}
viewType.FirstPersonCamera = firstPersonCamera;
}
#endif
/// <summary>
/// Serialize all of the view types to the ViewTypeData array.
/// </summary>
/// <param name="cameraController">The camera controller to serialize.</param>
public static void SerializeViewTypes(CameraController cameraController)
{
var viewTypes = new List<ViewType>(cameraController.ViewTypes);
cameraController.ViewTypeData = Shared.Utility.Serialization.Serialize<ViewType>(viewTypes);
#if UNITY_EDITOR
UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(cameraController);
#endif
cameraController.ViewTypes = viewTypes.ToArray();
}
/// <summary>
/// Returns the AddState of the specified view type.
/// </summary>
/// <param name="type">The view type.</param>
/// <returns>The AddState of the specified ability type. Can be null.</returns>
private static AddState[] GetAddStates(Type type)
{
AddState[] addStates;
if (s_AddStates.TryGetValue(type, out addStates)) {
return addStates;
}
if (type.GetCustomAttributes(typeof(AddState), true).Length > 0) {
addStates = type.GetCustomAttributes(typeof(AddState), true) as AddState[];
}
s_AddStates.Add(type, addStates);
return addStates;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 42c0264a57605f24684775571453dda2
timeCreated: 1513110789
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,572 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility
{
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// A collection of math functions.
/// </summary>
public class MathUtility
{
// The multiplier when converting from the CharacterLocomotion force to a Rigidbody force.
public const float RigidbodyForceMultiplier = 50;
private static Dictionary<Collider, Transform> m_ColliderTransformMap = new Dictionary<Collider, Transform>();
/// <summary>
/// Returns the friction value between material1 and material2.
/// </summary>
/// <param name="material1">The first material to get the friction value of.</param>
/// <param name="material2">The second material to get the friction value of.</param>
/// <returns>The combined friction value.</returns>
public static float FrictionValue(PhysicsMaterial material1, PhysicsMaterial material2, bool dynamicFriction)
{
if (material1.frictionCombine == PhysicsMaterialCombine.Maximum || material2.frictionCombine == PhysicsMaterialCombine.Maximum) {
return dynamicFriction ? Mathf.Max(material1.dynamicFriction, material2.dynamicFriction) : Mathf.Max(material1.staticFriction, material2.staticFriction);
}
if (material1.frictionCombine == PhysicsMaterialCombine.Minimum || material2.frictionCombine == PhysicsMaterialCombine.Minimum) {
return dynamicFriction ? Mathf.Min(material1.dynamicFriction, material2.dynamicFriction) : Mathf.Min(material1.staticFriction, material2.staticFriction);
}
if (material1.frictionCombine == PhysicsMaterialCombine.Multiply || material2.frictionCombine == PhysicsMaterialCombine.Multiply) {
return dynamicFriction ? (material1.dynamicFriction * material2.dynamicFriction) : (material1.staticFriction * material2.staticFriction);
}
return dynamicFriction ? ((material1.dynamicFriction + material2.dynamicFriction) / 2) : ((material1.staticFriction + material2.staticFriction) / 2); // Average combine.
}
/// <summary>
/// Returns the bounciness value between material1 and material2.
/// </summary>
/// <param name="material1">The first material to get the bounciness value of.</param>
/// <param name="material2">The second material to get the bounciness value of.</param>
/// <returns>The combined bounciness value.</returns>
public static float BouncinessValue(PhysicsMaterial material1, PhysicsMaterial material2)
{
if (material1.bounceCombine == PhysicsMaterialCombine.Maximum || material2.bounceCombine == PhysicsMaterialCombine.Maximum) {
return Mathf.Max(material1.bounciness, material2.bounciness);
}
if (material1.bounceCombine == PhysicsMaterialCombine.Minimum || material2.bounceCombine == PhysicsMaterialCombine.Minimum) {
return Mathf.Min(material1.bounciness, material2.bounciness);
}
if (material1.bounceCombine == PhysicsMaterialCombine.Multiply || material2.bounceCombine == PhysicsMaterialCombine.Multiply) {
return (material1.bounciness * material2.bounciness);
}
return (material1.bounciness + material2.bounciness) / 2; // Average combine.
}
/// <summary>
/// Transforms the position from local space to world space. This is similar to Transform.TransformPoint but does not require a Transform.
/// </summary>
/// <param name="worldPosition">The world position of the object.</param>
/// <param name="rotation">The world rotation of the object.</param>
/// <param name="localPosition">The local position of the object</param>
/// <returns>The world space position.</returns>
public static Vector3 TransformPoint(Vector3 worldPosition, Quaternion rotation, Vector3 localPosition)
{
return worldPosition + (rotation * localPosition);
}
/// <summary>
/// Transforms the position from world space to local space. This is similar to Transform.InverseTransformPoint but does not require a Transform.
/// </summary>
/// <param name="worldPosition">The world position of the object.</param>
/// <param name="rotation">The world rotation of the object.</param>
/// <param name="position">The position of the object.</param>
/// <returns>The local space position.</returns>
public static Vector3 InverseTransformPoint(Vector3 worldPosition, Quaternion rotation, Vector3 position)
{
var diff = position - worldPosition;
return Quaternion.Inverse(rotation) * diff;
}
/// <summary>
/// Transforms the direction from local space to world space. This is similar to Transform.TransformDirection but does not require a Transform.
/// </summary>
/// <param name="direction">The direction to transform from local space to world space.</param>
/// <param name="rotation">The world rotation of the object.</param>
/// <returns>The world space direction.</returns>
public static Vector3 TransformDirection(Vector3 direction, Quaternion rotation)
{
return rotation * direction;
}
/// <summary>
/// Transforms the direction from world space to local space. This is similar to Transform.InverseTransformDirection but does not require a Transform.
/// </summary>
/// <param name="direction">The direction to transform from world space to local space.</param>
/// <param name="rotation">The world rotation of the object.</param>
/// <returns>The local space direction.</returns>
public static Vector3 InverseTransformDirection(Vector3 direction, Quaternion rotation)
{
return Quaternion.Inverse(rotation) * direction;
}
/// <summary>
/// Transforms the rotation from local space to world space.
/// </summary>
/// <param name="worldRotation">The world rotation of the object.</param>
/// <param name="rotation">The rotation to transform from local space to world space.</param>
/// <returns>The world space rotation.</returns>
public static Quaternion TransformQuaternion(Quaternion worldRotation, Quaternion rotation)
{
return worldRotation * rotation;
}
/// <summary>
/// Transforms the rotation from world space to local space.
/// </summary>
/// <param name="worldRotation">The world rotation of the object.</param>
/// <param name="rotation">The rotation to transform from world space to local space.</param>
/// <returns>The local space rotation.</returns>
public static Quaternion InverseTransformQuaternion(Quaternion worldRotation, Quaternion rotation)
{
return Quaternion.Inverse(worldRotation) * rotation;
}
/// <summary>
/// Determines the endcaps of a capsule.
/// </summary>
/// <param name="capsuleCollider">The CapsuleCollider to determine the endcaps of.</param>
/// <param name="position">The position of the CapsuleCollider's transform.</param>
/// <param name="rotation">The rotation of the CapsuleCollider's transform.</param>
/// <param name="firstEndCap">The first resulting endcap.</param>
/// <param name="secondEndCap">The second resulting endcap.</param>
public static void CapsuleColliderEndCaps(CapsuleCollider capsuleCollider, Vector3 position, Quaternion rotation, out Vector3 firstEndCap, out Vector3 secondEndCap)
{
var direction = CapsuleColliderDirection(capsuleCollider);
var heightMultiplier = CapsuleColliderHeightMultiplier(capsuleCollider);
var radiusMultipler = ColliderRadiusMultiplier(capsuleCollider);
firstEndCap = TransformPoint(position, rotation, Vector3.Scale(capsuleCollider.center, capsuleCollider.transform.lossyScale) + direction * (-(capsuleCollider.height * heightMultiplier * 0.5f) + capsuleCollider.radius * radiusMultipler));
secondEndCap = firstEndCap + (rotation * direction) * (capsuleCollider.height * heightMultiplier - capsuleCollider.radius * radiusMultipler * 2);
}
/// <summary>
/// Determines the endcaps of a capsule.
/// </summary>
/// <param name="height">The height of the CapsuleCollider.</param>
/// <param name="radius">The radius of the CapsuleCollider.</param>
/// <param name="center">The center of the CapsuleCollider.</param>
/// <param name="direction">The direction of the CapsuleCollider.</param>
/// <param name="position">The position of the CapsuleCollider's transform.</param>
/// <param name="rotation">The rotation of the CapsuleCollider's transform.</param>
/// <param name="firstEndCap">The first resulting endcap.</param>
/// <param name="secondEndCap">The second resulting endcap.</param>
public static void CapsuleColliderEndCaps(float height, float radius, Vector3 center, Vector3 direction, Vector3 position, Quaternion rotation, out Vector3 firstEndCap, out Vector3 secondEndCap)
{
firstEndCap = TransformPoint(position, rotation, center + direction * (-(height * 0.5f) + radius));
secondEndCap = firstEndCap + (rotation * direction) * (height - radius * 2);
}
/// <summary>
/// Returns the world direction that the CapsuleCollider is facing.
/// </summary>
/// <param name="capsuleCollider">The CapsuleCollider to determine the direction that it is facing.</param>
/// <returns>The world direction of the CapsuleCollider.</returns>
public static Vector3 CapsuleColliderDirection(CapsuleCollider capsuleCollider)
{
Vector3 direction;
if (capsuleCollider.direction == 1) { // Y-Axis.
direction = Vector3.up;
} else if (capsuleCollider.direction == 2) { // Z-Axis.
direction = Vector3.forward;
} else { // X-Axis.
direction = Vector3.right;
}
return direction;
}
/// <summary>
/// Clamp the angle between -180 and 180 degrees.
/// </summary>
/// <param name="angle">The angle to clamp.</param>
/// <returns>An angle between -180 and 180 degrees.</returns>
public static float ClampInnerAngle(float angle)
{
if (angle < -180) {
angle += 360;
}
if (angle > 180) {
angle -= 360;
}
return angle;
}
/// <summary>
/// Clamp the angle between 0 and 360 degrees.
/// </summary>
/// <param name="angle">The angle to clamp.</param>
/// <returns>An angle between 0 and 360 degrees.</returns>
public static float ClampAngle(float angle)
{
if (angle < 0) {
angle += 360;
}
if (angle > 360) {
angle -= 360;
}
return angle;
}
/// <summary>
/// Clamp the angle between min and max degrees.
/// </summary>
/// <param name="angle">The angle to clamp.</param>
/// <param name="min">The minimum angle range.</param>
/// <param name="max">The maximum angle range.</param>
/// <returns>An angle between min and max degrees.</returns>
public static float ClampAngle(float angle, float min, float max)
{
var minDiff = ClampInnerAngle(min - angle);
var maxDiff = ClampInnerAngle(angle - max);
if (Mathf.Abs(minDiff) < Mathf.Abs(maxDiff)) {
if (minDiff <= 0) {
return angle;
}
return min;
}
if (maxDiff <= 0) {
return angle;
}
return max;
}
/// <summary>
/// Clamp the angle between min and max degrees.
/// </summary>
/// <param name="angle">The original angle to clamp.</param>
/// <param name="deltaAngle">The angle to add to the original angle.</param>
/// <param name="min">The minimum angle range.</param>
/// <param name="max">The maximum angle range.</param>
/// <returns>An angle between min and max degrees.</returns>
public static float ClampAngle(float angle, float deltaAngle, float min, float max)
{
var minDiff = ClampInnerAngle(min - angle);
var maxDiff = ClampInnerAngle(angle - max);
if (Mathf.Abs(minDiff) < Mathf.Abs(maxDiff)) {
if (ClampInnerAngle(min - (angle + deltaAngle)) <= 0) {
return (angle + deltaAngle);
}
return min;
}
if (ClampInnerAngle((angle + deltaAngle) - max) <= 0) {
return (angle + deltaAngle);
}
return max;
}
/// <summary>
/// Returns the rotation of the specified matrix.
/// </summary>
/// <param name="matrix">The matrix to get the rotation of.</param>
/// <returns>The rotation of the specified matrix.</returns>
public static Quaternion QuaternionFromMatrix(Matrix4x4 matrix)
{
return Quaternion.LookRotation(matrix.GetColumn(2), matrix.GetColumn(1));
}
/// <summary>
/// Returns the position of the specified matrix.
/// </summary>
/// <param name="matrix">The matrix to get the position of.</param>
/// <returns>The rotation of the specified matrix.</returns>
public static Vector3 PositionFromMatrix(Matrix4x4 matrix)
{
return matrix.GetColumn(3);
}
/// <summary>
/// Returns the matrix of the first Transform with the deltaRotation applied to the root Transform. This is similar to calling Transform.rotation = value on
/// the root Transform and getting the position/rotation of the child.
/// </summary>
/// <param name="current">The current Transform to add to the matrix.</param>
/// <param name="root">The base Transform that should have the delta rotation applied to.</param>
/// <param name="deltaRotation">The rotation to apply to the root Transform.</param>
/// <returns>The matrix of the first Transform with the deltaRotation applied to the root Transform.</returns>
public static Matrix4x4 ApplyRotationToChildMatrices(Transform current, Transform root, Quaternion deltaRotation)
{
// Recursively multiply the matrices as long as the current Transform is not at the root.
if (current != root) {
return ApplyRotationToChildMatrices(current.parent, root, deltaRotation) * Matrix4x4.TRS(current.localPosition, current.localRotation, current.localScale);
}
// At the root of the tree, apply the delta to the rotation and return the matrix.
return Matrix4x4.TRS(current.localPosition, current.localRotation * deltaRotation, current.localScale);
}
/// <summary>
/// Returns the closest point on a capsule or sphere collider.
/// </summary>
/// <param name="transform">The parent transform of the object which contains the collider.</param>
/// <param name="collider">The collider to get the closest point of.</param>
/// <param name="point">The point used to find the closest point on the collider.</param>
/// <param name="moveDirection">The direction that the character is moving.</param>
/// <param name="sphereCheck">Should a sphere check be performed? If false the Pythagorean theorem will be used.</param>
/// <param name="lowerPoint">Should the lower point of the collider be returned? Used by the ground check to always return the lowest point.</param>
/// <returns>The closest point on the collider.</returns>
public static Vector3 ClosestPointOnCollider(Transform transform, Collider collider, Vector3 point, Vector3 moveDirection, bool sphereCheck, bool lowerPoint)
{
if (collider is CapsuleCollider) {
return ClosestPointOnCapsule(transform, collider as CapsuleCollider, point, moveDirection, sphereCheck, lowerPoint);
} else { // SphereCollider.
var sphereCollider = collider as SphereCollider;
return ClosestPointOnSphere(transform, point, collider.transform.TransformPoint(sphereCollider.center), sphereCollider.radius * ColliderRadiusMultiplier(collider), sphereCheck, lowerPoint);
}
}
/// <summary>
/// Returns the closest point on a CapsuleCollider.
/// </summary>
/// <param name="transform">The parent transform of the object which contains the collider.</param>
/// <param name="capsuleCollider">The CapsuleCollider to get the closest point of.</param>
/// <param name="point">The point used to find the closest point on the collider.</param>
/// <param name="moveDirection">The direction that the character is moving.</param>
/// <param name="sphereCheck">Should a sphere check be performed? If false the Pythagorean theorem will be used.</param>
/// <param name="lowerPoint">Should the lower point of the collider be returned? Used by the ground check to always return the lowest point.</param>
/// <returns>The closest point on a capsule.</returns>
private static Vector3 ClosestPointOnCapsule(Transform transform, CapsuleCollider capsuleCollider, Vector3 point, Vector3 moveDirection, bool sphereCheck, bool lowerPoint)
{
Vector3 capsuleDirection;
if (capsuleCollider.direction == 1) { // Y-Axis.
capsuleDirection = capsuleCollider.transform.up;
} else if (capsuleCollider.direction == 2) { // Z-Axis.
capsuleDirection = capsuleCollider.transform.forward;
} else { // X-Axis.
capsuleDirection = capsuleCollider.transform.right;
}
var heightMultiplier = CapsuleColliderHeightMultiplier(capsuleCollider);
var radiusMultiplier = ColliderRadiusMultiplier(capsuleCollider);
// If the hit point is within the spheres of the Capsule Collider then the collider position should be based off of the Capsule Collider length (using the point projected onto
// a cylinder forumla). If the hit point is on the ends of the Capsule Collider then the Calsule Collider caps should be used (or, based off of a sphere).
var capsuleCenter = capsuleCollider.transform.TransformPoint(capsuleCollider.center) + moveDirection;
var capsuleLength = ((capsuleCollider.height * heightMultiplier * 0.5f) - capsuleCollider.radius * radiusMultiplier);
var start = capsuleCenter - capsuleDirection * capsuleLength;
var end = capsuleCenter + capsuleDirection * capsuleLength;
var hitDirection = (point - capsuleCenter).normalized;
// Use the project point on segment forumla to determine if the closest point is on the segment or the endcap.
var pointStartDirection = point - start;
var endStartDirection = end - start;
var segment = (Vector3.Dot(pointStartDirection, endStartDirection) / Vector3.Dot(endStartDirection, endStartDirection));
if (segment >= 0 && segment <= 1) { // On cylinder.
// If the point is on the segment then the collision point is within the collider.
var closestPoint = start + segment * endStartDirection;
var pointDirection = (point - closestPoint).normalized * capsuleCollider.radius * radiusMultiplier;
if (lowerPoint) {
// If the direction is above the collider then inverse the direction. This will prevent the closest point being on top of the collider when it should be on the bottom.
var localCylinderDirection = transform.InverseTransformDirection(pointDirection);
if (localCylinderDirection.y > 0) {
localCylinderDirection.y *= -1;
pointDirection = transform.TransformDirection(localCylinderDirection);
}
}
return closestPoint + pointDirection;
} else { // On sphere.
if (lowerPoint) {
// If the direction is above the collider then inverse the direction. This will prevent the closest point being on top of the collider when it should be on the bottom.
var localHitDirection = transform.InverseTransformDirection(hitDirection);
if (localHitDirection.y > 0) {
localHitDirection.y *= -1;
hitDirection = transform.TransformDirection(localHitDirection);
}
}
var dot = Vector3.Dot(capsuleDirection, hitDirection);
var sphereCenter = capsuleCenter + (capsuleDirection * capsuleLength * Mathf.Sign(dot));
return ClosestPointOnSphere(transform, point, sphereCenter, capsuleCollider.radius * radiusMultiplier, sphereCheck, lowerPoint);
}
}
/// <summary>
/// Returns the closest point on a SphereCollider.
/// </summary>
/// <param name="transform">The parent transform of the object which contains the collider.</param>
/// <param name="point">The point used to find the closest point on the collider.</param>
/// <param name="sphereCenter">The center of the sphere.</param>
/// <param name="radius">The radius of the sphere.</param>
/// <param name="sphereCheck">Should a sphere check be performed? If false the Pythagorean theorem will be used.</param>
/// <returns>The closest point on a sphere.</returns>
private static Vector3 ClosestPointOnSphere(Transform transform, Vector3 point, Vector3 sphereCenter, float radius, bool sphereCheck, bool lowerPoint)
{
var position = Vector3.zero;
var localDirection = InverseTransformPoint(sphereCenter, transform.rotation, point);
if (sphereCheck || localDirection.y > radius) {
// Use the standard closest point on a sphere algorithm.
var direction = (point - sphereCenter).normalized;
if (lowerPoint) {
// If the direction is above the collider then inverse the direction. This will prevent the closest point being on top of the collider when it should be on the bottom.
var localSphereDirection = transform.InverseTransformDirection(direction);
if (localSphereDirection.y > 0) {
localSphereDirection.y *= -1;
direction = transform.TransformDirection(localSphereDirection);
}
}
position = sphereCenter + (direction * radius);
} else {
// Use the Pythagorean theorem to determine the point. This won't return the closest point but it will return the point that the collider should adjust to.
// Ignore the local y value because the Pythagorean theorem is used to determine the y position.
localDirection.y = 0;
var magnitude = localDirection.magnitude;
if (magnitude < radius) {
position = sphereCenter - transform.up * Mathf.Sqrt((radius * radius) - (magnitude * magnitude));
} else {
position = sphereCenter - transform.up * radius;
}
}
return position;
}
/// <summary>
/// Returns the CapsuleCollider height multipler based off of the scale.
/// </summary>
/// <param name="capsuleCollider">The CapsuleCollider to determine the height multiplier of.</param>
/// <returns>The capsule collider height multipler based off of the scale.</returns>
public static float CapsuleColliderHeightMultiplier(CapsuleCollider capsuleCollider)
{
// Use the cached transform for quick lookup.
Transform transform;
if (!m_ColliderTransformMap.TryGetValue(capsuleCollider, out transform)) {
transform = capsuleCollider.transform;
m_ColliderTransformMap.Add(capsuleCollider, transform);
}
if (capsuleCollider.direction == 1) { // Y-axis.
return transform.lossyScale.y;
} else if (capsuleCollider.direction == 2) { // Z-axis.
return transform.lossyScale.z;
}
return transform.lossyScale.x;
}
/// <summary>
/// Returns the radius multipler of the collider based off of the scale.
/// </summary>
/// <param name="collider">The collider determine the radius multiplier of.</param>
/// <returns>The radius multipler of the collider based off of the scale.</returns>
public static float ColliderRadiusMultiplier(Collider collider)
{
// Use the cached transform for quick lookup.
Transform transform;
if (!m_ColliderTransformMap.TryGetValue(collider, out transform)) {
transform = collider.transform;
m_ColliderTransformMap.Add(collider, transform);
}
var lossyScale = transform.lossyScale;
if (collider is CapsuleCollider) {
var capsuleCollider = collider as CapsuleCollider;
if (capsuleCollider.direction == 1) { // Y-axis.
return Mathf.Max(lossyScale.x, lossyScale.z);
} else if (capsuleCollider.direction == 2) { // Z-axis.
return Mathf.Max(lossyScale.x, lossyScale.y);
}
return Mathf.Max(lossyScale.y, lossyScale.z);
} else { // SphereCollider.
return Mathf.Max(lossyScale.x, Mathf.Max(lossyScale.y, lossyScale.z));
}
}
/// <summary>
/// Is the point under the Collider?
/// </summary>
/// <param name="transform">The Collider's Transform.</param>
/// <param name="collider">The interested Collider.</param>
/// <param name="point">The point to check if under the Collider.</param>
/// <returns>Returns true if the point is under the Collider.</returns>
public static bool IsUnderCollider(Transform transform, Collider collider, Vector3 point)
{
var center = (collider is SphereCollider ? (collider as SphereCollider).center : (collider as CapsuleCollider).center);
var direction = transform.InverseTransformDirection(point - collider.transform.TransformPoint(center));
return direction.y <= 0.001f;
}
/// <summary>
/// Returns the height of the collider.
/// </summary>
/// <param name="transform">The transform used to determine the up direction.</param>
/// <param name="collider">The collider to get the height of.</param>
/// <returns>The height of the collider.</returns>
public static float LocalColliderHeight(Transform transform, Collider collider)
{
// The height of the collider is determined by the uppermost point on the collider transformed into the local position of the object.
var maxValue = (collider is CapsuleCollider ? (collider as CapsuleCollider).height : (collider as SphereCollider).radius) * 100;
var topPosition = ClosestPointOnCollider(transform, collider, transform.TransformPoint(0, maxValue, 0), Vector3.zero, true, false);
return transform.InverseTransformPoint(topPosition).y;
}
/// <summary>
/// Returns the invese of pow.
/// </summary>
/// <param name="b">The base value.</param>
/// <param name="value">The value computed by pow.</param>
/// <returns>The inverse of pow.</returns>
public static float InversePow(float b, float value)
{
return Mathf.Log(value) / Mathf.Log(b);
}
/// <summary>
/// Rounds the specified value according to the number of decimals.
/// </summary>
/// <param name="value">The value to round.</param>
/// <param name="factor">The factor to round to.</param>
/// <returns>The roudned value.</returns>
public static float Round(float value, int factor)
{
return Mathf.Round(value * factor) / factor;
}
/// <summary>
/// Rounds the specified value according to the number of decimals.
/// </summary>
/// <param name="value">The value to round.</param>
/// <param name="factor">The factor to round to.</param>
/// <returns>The roudned value.</returns>
public static Quaternion Round(Quaternion value, int factor)
{
value.x = Round(value.x, factor);
value.y = Round(value.y, factor);
value.z = Round(value.z, factor);
value.w = Round(value.w, factor);
return value;
}
/// <summary>
/// Retrusn true if the specified scale is almost uniform. An epsilon value is used so the scale doesn't have to be
/// precisely uniform.
/// </summary>
/// <param name="scale">The scale to determine if it is uniform.</param>
/// <returns>True if the specified scale is almost uniform.</returns>
public static bool IsUniform(Vector3 scale)
{
return Mathf.Abs(scale.x - scale.y) < 0.00001f && Mathf.Abs(scale.y - scale.z) < 0.00001f;
}
/// <summary>
/// Returns true if layer is within the layerMask.
/// </summary>
/// <param name="layer">The layer to check.</param>
/// <param name="layerMask">The mask to compare against.</param>
/// <returns>True if the layer is within the layer mask.</returns>
public static bool InLayerMask(int layer, int layerMask)
{
return ((1 << layer) & layerMask) == (1 << layer);
}
/// <summary>
/// Concatenate three integers into one. The first int will occupy the millions place, the second int will occupy the thousands place, and the third
/// int will occupy the hundeds place. For example, a value of 30, 52, 1 will return 30052001.
/// </summary>
/// <param name="a">The first integer to concatentate.</param>
/// <param name="a">The second integer to concatentate.</param>
/// <param name="a">The third integer to concatentate.</param>
/// <returns>The concatenated integer.</returns>
public static int Concatenate(int a, int b, int c)
{
return (a * 1000000) + (b * 1000) + c;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 9f981c13c149c654d96deaf001d48424
timeCreated: 1472412370
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,107 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility
{
using System.Collections.Generic;
/// <summary>
/// The QuickSelect algorithm is a selection algorithm that uses a similar method as the QuickSort sorting algorithm. More information can be found on this page:
/// https://en.wikipedia.org/wiki/Quickselect.
/// </summary>
public class QuickSelect
{
/// <summary>
/// Returns the element that is the Kth smallest within the array.
/// </summary>
/// <param name="array">The array that should be searched.</param>
/// <param name="arrayCount">The number of elements to search within the array.</param>
/// <param name="k">The nth smallest value to retrieve. 0 indicates the smallest element, endIndex - 1 indicates the largest.</param>
/// <param name="comparer">The IComparer used to compare the array.</param>
/// <returns>The element that is the Kth smallest within the array.</returns>
public static T SmallestK<T>(T[] array, int arrayCount, int k, IComparer<T> comparer)
{
if (k > arrayCount - 1) {
k = arrayCount - 1;
}
return SmallestK<T>(array, 0, arrayCount - 1, k, comparer);
}
/// <summary>
/// Returns the element that is the Kth smallest within the array.
/// </summary>
/// <param name="array">The array that should be searched.</param>
/// <param name="startIndex">The starting index of the array.</param>
/// <param name="endIndex">The ending index of the array.</param>
/// <param name="k">The nth smallest value to retrieve. 0 indicates the smallest element, endIndex - 1 indicates the largest.</param>
/// <param name="comparer">The IComparer used to compare the array.</param>
/// <returns>The element that is the Kth smallest within the array.</returns>
private static T SmallestK<T>(T[] array, int startIndex, int endIndex, int k, IComparer<T> comparer)
{
if (startIndex == endIndex) {
return array[startIndex];
}
// Similar to the QuickSort algorithm, split the array into a subset and reorder based on the pivot.
var pivotIndex = Partition(array, startIndex, endIndex, comparer);
// If the pivot is same as k then the kth smallest value has been found.
if (pivotIndex == k) {
return array[pivotIndex];
}
// If the pivot is less, then the Kth smallest element is in the right subgroup.
if (pivotIndex < k) {
return SmallestK(array, pivotIndex + 1, endIndex, k, comparer);
}
// If the pivot is greater, then the Kth smallest element is in the left subgroup.
return SmallestK<T>(array, startIndex, pivotIndex - 1, k, comparer);
}
/// <summary>
/// Partition the array into two groups based on the pivot. All values smaller than the pivot will be moved to the left, and all values greater will be moved
/// to the right. This is similar to the QuickSort algorithm.
/// </summary>
/// <param name="array">The array that should be sorted.</param>
/// <param name="startIndex">The starting index of the array.</param>
/// <param name="endIndex">The ending index of the array.</param>
/// <param name="k">The nth smallest value to retrieve. 0 indicates the smallest element, endIndex - 1 indicates the largest.</param>
/// <param name="comparer">The IComparer used to compare the array.</param>
/// <returns>The position of the pivot.</returns>
private static int Partition<T>(T[] array, int startIndex, int endIndex, IComparer<T> comparer)
{
var pivotIndex = UnityEngine.Random.Range(startIndex, endIndex + 1);
// The pivot has not been reordered yet. Move all elements that are less than the pivot to the left, and move all elements that are greater to the right.
var pivotValue = array[pivotIndex];
// The pivot should be moved to the end so it won't be compared against itself.
Swap(array, pivotIndex, endIndex);
var index = startIndex;
for (int i = startIndex; i < endIndex; ++i) {
if (comparer.Compare(array[i], pivotValue) < 0) {
Swap(array, index, i);
index++;
}
}
// Ensure the pivot is on the right of the smaller values.
Swap(array, index, endIndex);
return index;
}
/// <summary>
/// Swap the first and second elements.
/// </summary>
/// <param name="array">The array that should be sorted.</param>
/// <param name="firstIndex">The first index that should be swapped.</param>
/// <param name="secondIndex">The second index that should be swapped.</param>
private static void Swap<T>(T[] array, int firstIndex, int secondIndex)
{
var temp = array[firstIndex];
array[firstIndex] = array[secondIndex];
array[secondIndex] = temp;
}
}
}

View File

@@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: 406be0d1220094141b43b4d8b793e806
timeCreated: 1544079277
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,38 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility
{
using UnityEngine;
/// <summary>
/// Utility functions related to time.
/// </summary>
public class TimeUtility
{
// The target framerate. Application.targetFramerate can return 0 so it isn't used.
private const int c_TargetFramerate = 60;
/// <summary>
/// Returns an alternative delta time which is based on framerate where "delta 1" corresponds to 60 FPS.
/// </summary>
/// <returns>The target framerate-based delta time</returns>
public static float FramerateDeltaTime
{
get { return Time.deltaTime * c_TargetFramerate; }
}
/// <summary>
/// Returns the delta time modified by the timescale.
/// </summary>
/// <returns>Delta time modified by the timescale.</returns>
public static float DeltaTimeScaled
{
get { return Time.deltaTime * Time.timeScale; }
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 215426ae1b7a5094e83ec8f54692bc37
timeCreated: 1472498616
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,61 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility
{
using UnityEngine;
/// <summary>
/// Extension methods for the UnityEngine.Transform class.
/// </summary>
public static class TransformExtensions
{
/// <summary>
/// Sets the parent of the transform object to the specified parent.
/// </summary>
/// <param name="transform">The transform to set the parent of.</param>
/// <param name="parent">The parent of the transform.</param>
public static void SetParentOrigin(this Transform transform, Transform parent)
{
transform.parent = parent;
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;
transform.localScale = Vector3.one;
}
/// <summary>
/// Recursively sets the layer on all of the children.
/// </summary>
/// <param name="transform">The transform to set the layer on.</param>
/// <param name="layer">The layer to set.</param>
public static void SetLayerRecursively(this Transform transform, int layer)
{
transform.gameObject.layer = layer;
for (int i = 0; i < transform.childCount; ++i) {
transform.GetChild(i).SetLayerRecursively(layer);
}
}
/// <summary>
/// Returns the component of the specified type in the GameObject or any of its parents.
/// </summary>
/// <param name="transform">The transform to get the component on.</param>
/// <typeparam name="T">The type of component to return.</typeparam>
/// <returns>THe component of the specified type in the GameObject or any of its parents. Can be null.</returns>
public static T GetComponentInParentIncludeInactive<T>(this Transform transform) where T : Component
{
var parent = transform;
T component;
while (parent != null) {
if ((component = parent.GetComponent<T>()) != null) {
return component;
}
parent = parent.parent;
}
return null;
}
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 823a9b0920d78eb408c319a89abc2d7d
timeCreated: 1517708488
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,667 +0,0 @@
/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Utility
{
using Opsive.Shared.Game;
using Opsive.UltimateCharacterController.Camera;
using System;
using System.Reflection;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Contains a set of utility functions useful for interacting with the Unity Engine.
/// </summary>
public class UnityEngineUtility
{
private static Dictionary<string, Type> s_TypeLookup = new Dictionary<string, Type>();
private static List<Assembly> s_LoadedAssemblies = null;
private static Dictionary<GameObject, UnityEngine.Camera> s_GameObjectCameraMap = new Dictionary<GameObject, UnityEngine.Camera>();
public static HashSet<object> s_ObjectUpdated = new HashSet<object>();
public static ScheduledEventBase s_ObjectClearEvent;
private static Dictionary<FieldInfo, Dictionary<Type, bool>> s_FieldAttributeMap;
private static Dictionary<PropertyInfo, Dictionary<Type, bool>> s_PropertyAttributeMap;
/// <summary>
/// Searches through all of the loaded assembies for the specified type.
/// </summary>
/// <param name="name">The string value of the type.</param>
/// <returns>The found Type. Can be null.</returns>
public static Type GetType(string name)
{
if (string.IsNullOrEmpty(name)) {
return null;
}
Type type;
// Cache the results for quick repeated lookup.
if (s_TypeLookup.TryGetValue(name, out type)) {
return type;
}
type = Type.GetType(name);
// Look in the loaded assemblies.
if (type == null) {
if (s_LoadedAssemblies == null || s_LoadedAssemblies.Count == 0) {
#if NETFX_CORE && !UNITY_EDITOR
s_LoadedAssemblies = GetStorageFileAssemblies(typeName).Result;
#else
s_LoadedAssemblies = new List<Assembly>();
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; ++i) {
s_LoadedAssemblies.Add(assemblies[i]);
}
#endif
}
// Continue until the type is found.
for (int i = 0; i < s_LoadedAssemblies.Count; ++i) {
type = s_LoadedAssemblies[i].GetType(name);
if (type != null) {
break;
}
}
}
if (type == null) {
// TODO: QuickStart and QuickStop were renamed in version 2.1.3.
if (name == "Opsive.UltimateCharacterController.Character.Abilities.StartMovement") {
return GetType("Opsive.UltimateCharacterController.Character.Abilities.QuickStart");
}
if (name == "Opsive.UltimateCharacterController.Character.Abilities.StopMovement") {
return GetType("Opsive.UltimateCharacterController.Character.Abilities.QuickStop");
}
// TODO: Add-on directory was renamed in 2.1.5.
if (name.Contains("Opsive.UltimateCharacterController.Addons.")) {
return GetType(name.Replace("Opsive.UltimateCharacterController.Addons.", "Opsive.UltimateCharacterController.AddOns."));
}
}
if (type != null) {
s_TypeLookup.Add(name, type);
}
return type;
}
/// <summary>
/// Returns a friendly name for the specified type.
/// </summary>
/// <param name="type">The type to retieve the name of.</param>
/// <returns>A friendly name for the specified type.</returns>
public static string GetFriendlyName(Type type)
{
return GetFriendlyName(type.FullName, type.Name);
}
/// <summary>
/// Returns a friendly name for the specified type.
/// </summary>
/// <param name="fullName">The full name of the type.</param>
/// <param name="name">The name of the type.</param>
/// <returns>A friendly name for the specified type.</returns>
public static string GetFriendlyName(string fullName, string name)
{
if (fullName.Contains("FirstPersonController")) {
return "First Person " + name;
} else if (fullName.Contains("ThirdPersonController")) {
return "Third Person " + name;
}
return name;
}
/// <summary>
/// Returns true if the field has the specified attribute.
/// </summary>
/// <param name="field">The field to determine if it has the attribute.</param>
/// <param name="attribute">The attribute to compare against.</param>
/// <returns>Tue if the field has the specified attribute.</returns>
public static bool HasAttribute(FieldInfo field, Type attribute)
{
if (field == null) {
return false;
}
// Cache the results for quick repeated lookup.
if (s_FieldAttributeMap == null) {
s_FieldAttributeMap = new Dictionary<FieldInfo, Dictionary<Type, bool>>();
}
Dictionary<Type, bool> typeLookup;
if (!s_FieldAttributeMap.TryGetValue(field, out typeLookup)) {
typeLookup = new Dictionary<Type, bool>();
s_FieldAttributeMap.Add(field, typeLookup);
}
// The static field attribute map contains a dictionary of attributes that the specified type has. Add to that dictionary if the current
// attribute type hasn't been retrieved before.
var hasAttribute = false;
if (!typeLookup.TryGetValue(attribute, out hasAttribute)) {
hasAttribute = field.GetCustomAttributes(attribute, false).Length > 0;
typeLookup.Add(attribute, hasAttribute);
}
return hasAttribute;
}
/// <summary>
/// Returns true if the property has the specified attribute.
/// </summary>
/// <param name="property">The property to determine if it has the attribute.</param>
/// <param name="attribute">The attribute to compare against.</param>
/// <returns>Tue if the property has the specified attribute.</returns>
public static bool HasAttribute(PropertyInfo property, Type attribute)
{
if (property == null) {
return false;
}
// Cache the results for quick repeated lookup.
if (s_PropertyAttributeMap == null) {
s_PropertyAttributeMap = new Dictionary<PropertyInfo, Dictionary<Type, bool>>();
}
Dictionary<Type, bool> typeLookup;
if (!s_PropertyAttributeMap.TryGetValue(property, out typeLookup)) {
typeLookup = new Dictionary<Type, bool>();
s_PropertyAttributeMap.Add(property, typeLookup);
}
// The static property attribute map contains a dictionary of attributes that the specified type has. Add to that dictionary if the current
// attribute type hasn't been retrieved before.
var hasAttribute = false;
if (!typeLookup.TryGetValue(attribute, out hasAttribute)) {
hasAttribute = property.GetCustomAttributes(attribute, false).Length > 0;
typeLookup.Add(attribute, hasAttribute);
}
return hasAttribute;
}
/// <summary>
/// Returns the camera with the MainCamera tag or the camera with the CameraController attached.
/// </summary>
/// <param name="character">The character that the camera is attached to.</param>
/// <returns>The found camera (if any).</returns>
public static UnityEngine.Camera FindCamera(GameObject character)
{
UnityEngine.Camera camera;
if (character != null) {
if (s_GameObjectCameraMap.TryGetValue(character, out camera)) {
// The reference may be null if the scene changed.
if (camera != null) {
return camera;
}
// The reference is null - search for the camera again.
s_GameObjectCameraMap.Remove(character);
}
}
// First try to find the camera with the character attached. If no camera has the character attached the return the first camera with the CameraController.
camera = SearchForCamera(character);
if (camera == null) {
camera = SearchForCamera(null);
if (camera != null) {
// The camera controller's character field must be null or equal to the existing character.
var cameraController = camera.GetComponent<CameraController>();
if (cameraController.Character != null && cameraController.Character != character) {
camera = null;
}
}
}
if (camera != null && character != null) {
s_GameObjectCameraMap.Add(character, camera);
}
return camera;
}
/// <summary>
/// Loops through the cameras searching for a camera with the character assigned.
/// </summary>
/// <param name="character">The character to search for. Can be null.</param>
/// <returns>The camera with the character assigned.</returns>
private static UnityEngine.Camera SearchForCamera(GameObject character)
{
CameraController cameraController;
UnityEngine.Camera mainCamera;
if ((mainCamera = UnityEngine.Camera.main) != null && (cameraController = mainCamera.GetComponent<CameraController>()) != null && (character == null || cameraController.Character == character)) {
return mainCamera;
}
var cameraControllers = UnityEngine.Object.FindObjectsOfType<CameraController>();
for (int i = 0; i < cameraControllers.Length; ++i) {
if (character == null || cameraControllers[i].Character == character) {
return cameraControllers[i].GetComponent<UnityEngine.Camera>();
}
}
return null;
}
/// <summary>
/// Returns true if the specified object has been updated.
/// </summary>
/// <param name="obj">The object to check if it has been updated.</param>
/// <returns>True if the specified object has been updated.</returns>
public static bool HasUpdatedObject(object obj)
{
return s_ObjectUpdated.Contains(obj);
}
/// <summary>
/// Adds the specified object to the set.
/// </summary>
/// <param name="obj">The object that has been updated.</param>
public static void AddUpdatedObject(object obj)
{
AddUpdatedObject(obj, false);
}
/// <summary>
/// Adds the specified object to the set.
/// </summary>
/// <param name="obj">The object that has been updated.</param>
/// <param name="autoClear">Should the object updated map be automatically cleared on the next tick?</param>
public static void AddUpdatedObject(object obj, bool autoClear)
{
s_ObjectUpdated.Add(obj);
if (autoClear && s_ObjectClearEvent == null) {
s_ObjectClearEvent = Scheduler.Schedule(0.0001f, ClearUpdatedObjectsEvent);
}
}
/// <summary>
/// Removes all of the objects from the set.
/// </summary>
public static void ClearUpdatedObjects()
{
s_ObjectUpdated.Clear();
}
/// <summary>
/// Removes all of the objects from the set and sets the event to null.
/// </summary>
private static void ClearUpdatedObjectsEvent()
{
ClearUpdatedObjects();
s_ObjectClearEvent = null;
}
/// <summary>
/// Change the size of the RectTransform according to the size of the sprite.
/// </summary>
/// <param name="sprite">The sprite that the RectTransform should change its size to.</param>
/// <param name="spriteRectTransform">A reference to the sprite's RectTransform.</param>
public static void SizeSprite(Sprite sprite, RectTransform spriteRectTransform)
{
if (sprite != null) {
var sizeDelta = spriteRectTransform.sizeDelta;
sizeDelta.x = sprite.textureRect.width;
sizeDelta.y = sprite.textureRect.height;
spriteRectTransform.sizeDelta = sizeDelta;
}
}
/// <summary>
/// Clears the Unity Engine Utility cache.
/// </summary>
///
#if UNITY_2019_3_OR_NEWER
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
#endif
public static void ClearCache()
{
if (s_TypeLookup != null) { s_TypeLookup.Clear(); }
if (s_GameObjectCameraMap != null) { s_GameObjectCameraMap.Clear(); }
if (s_ObjectUpdated != null) { s_ObjectUpdated.Clear(); }
if (s_LoadedAssemblies != null) { s_LoadedAssemblies.Clear(); }
if (s_FieldAttributeMap != null) { s_FieldAttributeMap.Clear(); }
if (s_PropertyAttributeMap != null) { s_PropertyAttributeMap.Clear(); }
}
/// <summary>
/// Allows for comparison between RaycastHit objects.
/// </summary>
public class RaycastHitComparer : IComparer<RaycastHit>
{
/// <summary>
/// Compare RaycastHit x to RaycastHit y. If x has a smaller distance value compared to y then a negative value will be returned.
/// If the distance values are equal then 0 will be returned, and if y has a smaller distance value compared to x then a positive value will be returned.
/// </summary>
/// <param name="x">The first RaycastHit to compare.</param>
/// <param name="y">The second RaycastHit to compare.</param>
/// <returns>The resulting difference between RaycastHit x and y.</returns>
public int Compare(RaycastHit x, RaycastHit y)
{
if (x.transform == null) {
return int.MaxValue;
}
if (y.transform == null) {
return int.MinValue;
}
return x.distance.CompareTo(y.distance);
}
}
/// <summary>
/// Allows for equity comparison checks between RaycastHit objects.
/// </summary>
public struct RaycastHitEqualityComparer : IEqualityComparer<RaycastHit>
{
/// <summary>
/// Determines if RaycastHit x is equal to RaycastHit y.
/// </summary>
/// <param name="x">The first RaycastHit to compare.</param>
/// <param name="y">The second RaycastHit to compare.</param>
/// <returns>True if the raycasts are equal.</returns>
public bool Equals(RaycastHit x, RaycastHit y)
{
if (x.distance != y.distance) {
return false;
}
if (x.point != y.point) {
return false;
}
if (x.normal != y.normal) {
return false;
}
if (x.transform != y.transform) {
return false;
}
return true;
}
/// <summary>
/// Returns a hash code for the RaycastHit.
/// </summary>
/// <param name="hit">The RaycastHit to get the hash code of.</param>
/// <returns>The hash code for the RaycastHit.</returns>
public int GetHashCode(RaycastHit hit)
{
// Don't use hit.GetHashCode because that has boxing. This hash function won't always prevent duplicates but it's fine for what it's used for.
return ((int)(hit.distance * 10000)) ^ ((int)(hit.point.x * 10000)) ^ ((int)(hit.point.y * 10000)) ^ ((int)(hit.point.z * 10000)) ^
((int)(hit.normal.x * 10000)) ^ ((int)(hit.normal.y * 10000)) ^ ((int)(hit.normal.z * 10000));
}
}
}
/// <summary>
/// A container for a min and max float value.
/// </summary>
[Serializable]
public struct MinMaxFloat
{
[Tooltip("The minimum Vector3 value.")]
[SerializeField] private float m_MinValue;
[Tooltip("The maximum Vector3 value.")]
[SerializeField] private float m_MaxValue;
public float MinValue { get { return m_MinValue; } set { m_MinValue = value; } }
public float MaxValue { get { return m_MaxValue; } set { m_MaxValue = value; } }
public float RandomValue
{
get
{
return UnityEngine.Random.Range(m_MinValue, m_MaxValue);
}
}
/// <summary>
/// MinMaxFloat constructor which can specify the min and max values.
/// </summary>
/// <param name="minValue">The minimum float value.</param>
/// <param name="maxValue">The maximum float value.</param>
public MinMaxFloat(float minValue, float maxValue)
{
m_MinValue = minValue;
m_MaxValue = maxValue;
}
}
/// <summary>
/// A container for a min and max Vector3 value.
/// </summary>
[Serializable]
public struct MinMaxVector3
{
[Tooltip("The minimum Vector3 value.")]
[SerializeField] private Vector3 m_MinValue;
[Tooltip("The maximum Vector3 value.")]
[SerializeField] private Vector3 m_MaxValue;
[Tooltip("The minimum magnitude value when determining a random value.")]
[SerializeField] private Vector3 m_MinMagnitude;
public Vector3 MinValue { get { return m_MinValue; } set { m_MinValue = value; } }
public Vector3 MaxValue { get { return m_MaxValue; } set { m_MaxValue = value; } }
public Vector3 MinMagnitude { get { return m_MinMagnitude; } set { m_MinMagnitude = value; } }
public Vector3 RandomValue
{
get
{
var value = Vector3.zero;
value.x = GetRandomFloat(m_MinValue.x, m_MaxValue.x, m_MinMagnitude.x);
value.y = GetRandomFloat(m_MinValue.y, m_MaxValue.y, m_MinMagnitude.y);
value.z = GetRandomFloat(m_MinValue.z, m_MaxValue.z, m_MinMagnitude.z);
return value;
}
}
/// <summary>
/// MinMaxVector3 constructor which can specify the min and max values.
/// </summary>
/// <param name="minValue">The minimum Vector3 value.</param>
/// <param name="maxValue">The maximum Vector3 value.</param>
public MinMaxVector3(Vector3 minValue, Vector3 maxValue)
{
m_MinValue = minValue;
m_MaxValue = maxValue;
m_MinMagnitude = Vector3.zero;
}
/// <summary>
/// MinMaxVector3 constructor which can specify the min and max values.
/// </summary>
/// <param name="minValue">The minimum Vector3 value.</param>
/// <param name="maxValue">The maximum Vector3 value.</param>
/// <param name="minMagnitude">The minimum magnitude of the random value.</param>
public MinMaxVector3(Vector3 minValue, Vector3 maxValue, Vector3 minMagnitude)
{
m_MinValue = minValue;
m_MaxValue = maxValue;
m_MinMagnitude = minMagnitude;
}
/// <summary>
/// Returns a random float between the min and max value with the specified minimum magnitude.
/// </summary>
/// <param name="minValue">The minimum float value.</param>
/// <param name="maxValue">The maximum float value.</param>
/// <param name="minMagnitude">The minimum magnitude of the random value.</param>
/// <returns>A random float between the min and max value.</returns>
private float GetRandomFloat(float minValue, float maxValue, float minMagnitude)
{
if (minMagnitude != 0 && Mathf.Sign(m_MinValue.x) != Mathf.Sign(m_MaxValue.x)) {
if (Mathf.Sign(UnityEngine.Random.Range(m_MinValue.x, m_MaxValue.x)) > 0) {
return UnityEngine.Random.Range(minMagnitude, Mathf.Max(minMagnitude, maxValue));
}
return UnityEngine.Random.Range(-minMagnitude, Mathf.Min(-minMagnitude, minValue));
} else {
return UnityEngine.Random.Range(minValue, maxValue);
}
}
}
/// <summary>
/// Represents the object which can be spawned.
/// </summary>
[System.Serializable]
public class ObjectSpawnInfo
{
#pragma warning disable 0649
[Tooltip("The object that can be spawned.")]
[SerializeField] private GameObject m_Object;
[Tooltip("The probability that the object can be spawned.")]
[Range(0, 1)] [SerializeField] private float m_Probability = 1;
[Tooltip("Should a random spin be applied to the object after it has been spawned?")]
[SerializeField] private bool m_RandomSpin;
#pragma warning restore 0649
public GameObject Object { get { return m_Object; } }
public float Probability { get { return m_Probability; } }
public bool RandomSpin { get { return m_RandomSpin; } }
/// <summary>
/// Instantiate the object.
/// </summary>
/// <param name="position">The position to instantiate the object at.</param>
/// <param name="normal">The normal of the instantiated object.</param>
/// <param name="gravityDirection">The normalized direction of the character's gravity.</param>
/// <returns>The instantiated object (can be null). </returns>
public GameObject Instantiate(Vector3 position, Vector3 normal, Vector3 gravityDirection)
{
if (m_Object == null) {
return null;
}
// There is a random chance that the object cannot be spawned.
if (UnityEngine.Random.value < m_Probability) {
var rotation = Quaternion.LookRotation(normal);
// A random spin can be applied so the rotation isn't the same every hit.
if (m_RandomSpin) {
rotation *= Quaternion.AngleAxis(UnityEngine.Random.Range(0, 360), normal);
}
var instantiatedObject = ObjectPool.Instantiate(m_Object, position, rotation);
// If the DirectionalConstantForce component exists then the gravity direction should be set so the object will move in the correct direction.
var directionalConstantForce = instantiatedObject.GetCachedComponent<Traits.DirectionalConstantForce>();
if (directionalConstantForce != null) {
directionalConstantForce.Direction = gravityDirection;
}
return instantiatedObject;
}
return null;
}
}
/// <summary>
/// Struct which stores the material values to revert back to after the material has been faded.
/// </summary>
public struct OriginalMaterialValue
{
[Tooltip("The color of the material.")]
private Color m_Color;
[Tooltip("Does the material have a mode property?")]
private bool m_ContainsMode;
[Tooltip("The render mode of the material.")]
private float m_Mode;
[Tooltip("The SourceBlend BlendMode of the material.")]
private int m_SrcBlend;
[Tooltip("The DestinationBlend BlendMode of the material.")]
private int m_DstBlend;
[Tooltip("Is alpha blend enabled?")]
private bool m_AlphaBlend;
[Tooltip("The render queue of the material.")]
private int m_RenderQueue;
public Color Color { get { return m_Color; } set { m_Color = value; } }
public bool ContainsMode { get { return m_ContainsMode; } set { m_ContainsMode = value; } }
public float Mode { get { return m_Mode; } set { m_Mode = value; } }
public int SrcBlend { get { return m_SrcBlend; } set { m_SrcBlend = value; } }
public int DstBlend { get { return m_DstBlend; } set { m_DstBlend = value; } }
public bool AlphaBlend { get { return m_AlphaBlend; } set { m_AlphaBlend = value; } }
public int RenderQueue { get { return m_RenderQueue; } set { m_RenderQueue = value; } }
private static int s_ModeID;
private static int s_SrcBlendID;
private static int s_DstBlendID;
private static string s_AlphaBlendString = "_ALPHABLEND_ON";
public static int ModeID { get { return s_ModeID; } }
public static int SrcBlendID { get { return s_SrcBlendID; } }
public static int DstBlendID { get { return s_DstBlendID; } }
public static string AlphaBlendString { get { return s_AlphaBlendString; } }
/// <summary>
/// Initializes the OriginalMaterialValue.
/// </summary>
[RuntimeInitializeOnLoadMethod]
private static void Initialize()
{
s_ModeID = Shader.PropertyToID("_Mode");
s_SrcBlendID = Shader.PropertyToID("_SrcBlend");
s_DstBlendID = Shader.PropertyToID("_DstBlend");
}
/// <summary>
/// Initializes the OriginalMaterialValue to the material values.
/// </summary>
/// <param name="color">The material to initialize.</param>
/// <param name="colorID">The id of the color property.</param>
/// <param name="mode">Does the material have a Mode property?</param>
public void Initialize(Material material, int colorID, bool containsMode)
{
m_Color = material.GetColor(colorID);
m_AlphaBlend = material.IsKeywordEnabled(s_AlphaBlendString);
m_RenderQueue = material.renderQueue;
m_ContainsMode = containsMode;
if (containsMode) {
m_Mode = material.GetFloat(s_ModeID);
m_SrcBlend = material.GetInt(s_SrcBlendID);
m_DstBlend = material.GetInt(s_DstBlendID);
}
}
}
/// <summary>
/// Storage class for determining if an event is triggered based on an animation event or time.
/// </summary>
[System.Serializable]
public class AnimationEventTrigger
{
[Tooltip("Is the event triggered with a Unity animation event?")]
[SerializeField] private bool m_WaitForAnimationEvent;
[Tooltip("The amount of time it takes to trigger the event if not using an animation event.")]
[SerializeField] private float m_Duration;
public bool WaitForAnimationEvent { get { return m_WaitForAnimationEvent; } set { m_WaitForAnimationEvent = value; } }
public float Duration { get { return m_Duration; } set { m_Duration = value; } }
/// <summary>
/// Default constructor.
/// </summary>
public AnimationEventTrigger() { }
/// <summary>
/// Two parameter constructor for AnimationEventTrigger.
/// </summary>
/// <param name="waitForAnimationEvent">Is the event triggered with a Unity animation event?</param>
/// <param name="duration">The amount of time it takes to trigger the event if not using an animation event.</param>
public AnimationEventTrigger(bool waitForAnimationEvent, float duration)
{
m_WaitForAnimationEvent = waitForAnimationEvent;
m_Duration = duration;
}
}
/// <summary>
/// Attribute which allows the inspector to draw a foldout without the need of a custom editor.
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
public class InspectorFoldout : Attribute
{
private string m_Title;
public string Title { get { return m_Title; } }
public InspectorFoldout(string title)
{
m_Title = title;
}
}
/// <summary>
/// Attribute which allows the same type to be added multiple times.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class AllowDuplicateTypes : Attribute
{
// Intentionally left blank.
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 35e4a48599fbede4caef3244a9585f81
timeCreated: 1473985728
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: