Update
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12f2707fbd545fc4fbc3f704a078def7
|
||||
timeCreated: 1485983569
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dc93fb40c1f92a4a92118c3c1b98747
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16526568bd0b93842984441fd97bc59f
|
||||
timeCreated: 1513110789
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8e62d4b86ca89c40801df9a6e4900d9
|
||||
timeCreated: 1503625699
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0c054c10eb2cd343bd52134acc1df50
|
||||
timeCreated: 1513169106
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42c0264a57605f24684775571453dda2
|
||||
timeCreated: 1513110789
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f981c13c149c654d96deaf001d48424
|
||||
timeCreated: 1472412370
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 215426ae1b7a5094e83ec8f54692bc37
|
||||
timeCreated: 1472498616
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 823a9b0920d78eb408c319a89abc2d7d
|
||||
timeCreated: 1517708488
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35e4a48599fbede4caef3244a9585f81
|
||||
timeCreated: 1473985728
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user