void ResetCreationData() { characterToModify = null; characterName = ""; characterTag = "Default"; characterLayer = 0; playerOrNPC = PlayerOrNPC.player; //FriendOrFoe does not have friendly implemented yet. //friendOrFoe = FriendOrFoe.friendly; patrolType = PatrolType.circular; patrolObject = null; attackRange = 5; baseSpeed = 10; advancedCharacterInfo = false; shouldUseFieldOfView.target = false; fieldOfViewMat = null; obstacleLayer = 0; targetLayer = 0; fieldOfViewRadius = 15; fieldOfViewAngle = 82; characterModel = null; advancedObjectInfo = false; modelUsesEmptyParent = false; useSpecifiedParent.target = false; useSpecifiedTransformForHands.target = false; mainHand = null; offHand = null; mainHandName = ""; offHandName = ""; attackPoint = null; specifiedParent = null; doCreatePrefab = false; }
private void Initialize() { switch (myType) { case EnemyType.ARCHER: speed = 3; health = 50; break; case EnemyType.ONEHAND: speed = 2; health = 100; break; case EnemyType.TWOHAND: speed = 1; health = 150; break; default: speed = 2; health = 100; break; } patrolType = PatrolType.RANDOM; }
public void UpdateTaskGroupType() { int num1 = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; foreach (Ship ship in this.m_Ships) { if (ship.IsPolice) { ++num1; } else { switch (TaskGroup.GetTaskTypeFromShip(ship)) { case TaskGroupType.Passive: ++num4; continue; case TaskGroupType.Civilian: ++num5; continue; case TaskGroupType.Freighter: ++num2; continue; case TaskGroupType.UnArmed: ++num6; continue; case TaskGroupType.PlanetAssault: ++num7; continue; default: ++num3; continue; } } } this.m_Type = num1 <= 0 ? (num2 <= 0 ? (num6 <= 0 ? (!this.m_CommanderAI.IsEncounterCombat ? (num7 <= 0 ? (this.m_Ships.Count != 2 || num3 == this.m_Ships.Count || (num5 == this.m_Ships.Count || num4 == this.m_Ships.Count) ? (num5 <= num4 || num5 <= num3 ? (num3 <= num4 || num3 <= num5 ? TaskGroupType.Passive : (num5 <= num4 || num5 <= num3 / 5 ? TaskGroupType.Aggressive : TaskGroupType.Passive)) : (num3 > num4 ? TaskGroupType.Passive : TaskGroupType.Civilian)) : (num5 > 0 ? TaskGroupType.Passive : TaskGroupType.Aggressive)) : TaskGroupType.PlanetAssault) : TaskGroupType.Aggressive) : TaskGroupType.UnArmed) : TaskGroupType.Freighter) : TaskGroupType.Police; if (this.m_Type == TaskGroupType.Passive && (this.m_CommanderAI.GetAIType() == OverallAIType.PIRATE || this.m_CommanderAI.GetAIType() == OverallAIType.SLAVER)) { this.m_Type = TaskGroupType.Aggressive; } if (this.m_Type == TaskGroupType.Civilian || this.m_Type == TaskGroupType.Freighter || this.m_Type == TaskGroupType.Police) { this.m_PatrolType = PatrolType.Orbit; } else { this.m_PatrolType = PatrolType.Circular; } }
public TaskGroup(App game, CombatAI commandAI) { this.m_Game = game; this.m_CommanderAI = commandAI; this.m_Objective = (TacticalObjective)null; this.m_Orders = TaskGroupOrders.None; this.m_Type = TaskGroupType.Aggressive; this.m_bIsPlayerOrder = false; this.m_bIsInContactWithEnemy = false; this.m_EnemyGroupInContact = (EnemyGroup)null; this.m_Ships = new List <Ship>(); this.m_Targets = new List <Ship>(); this.m_ShipControls = new List <TaskGroupShipControl>(); this.m_TargetGroup = (EnemyGroup)null; this.m_TargetTaskGroup = (TaskGroup)null; this.m_PatrolType = PatrolType.Circular; this.m_RequestedObjectiveType = ObjectiveType.NO_OBJECTIVE; this.m_NumShipTypes = new int[14]; for (int index = 0; index < 14; ++index) { this.m_NumShipTypes[index] = 0; } this.m_GroupSpeed = 0.0f; this.m_RequestRefreshShipControls = false; this.m_ChangeAttackTime = 4800; this.m_CurrentChangeAttackDelay = this.m_ChangeAttackTime; }
/// <summary> /// Create a new waypoint list with target names /// </summary> /// <param name="ak">A AutoKillerScript.clsAutoKillerScript ak object used for calculating distances etc.</param> /// <param name="targetNames">An ArrayList of target names to associate with this PatrolArea</param> internal PatrolArea(AutoKillerScript.clsAutoKillerScript ak, ArrayList targetNames, PatrolType type, string name) { this._ak = ak; _type = type; _name = name; _mWaypoints = ArrayList.Synchronized(new ArrayList()); _mTargetNames = ArrayList.Synchronized(new ArrayList(targetNames)); }
/// <summary> /// Initializes a more specific patrol pattern /// </summary> /// <param name="enemy">Reference to the enemy that the AI is controlling</param> /// <param name="patrolType">Pattern of movement</param> /// <param name="walkSpeed">The distance traveled in one frame of movement</param> /// <param name="pauseLeft">The number of frames for the enemy to pause after stopping while facing left</param> /// <param name="pauseRight">The number of frames for the enemy to pause after stopping while facing right</param> public AI(Enemy enemy, PatrolType patrolType, double walkSpeed, int pauseLeft = 120, int pauseRight = 120) { this.enemy = enemy; this.patrolType = patrolType; this.walkSpeed = walkSpeed; this.pauseLeft = pauseLeft; this.pauseRight = pauseRight; patrolState = PatrolState.PauseRight; frameCounter = 0; }
public State_Patrol(Character character, List <Vector3> patrolPoints, Transform roamTransform, float roamRadius, PatrolType patrolType) : base(character) { this.patrolType = patrolType; this.patrolPoints = patrolPoints; this.roamTransform = roamTransform; this.roamRadius = roamRadius; if (lastPatrolPoint == null) { lastPatrolPoint = this.patrolPoints[0]; } }
public bool Search(string str) { if (WorldID.ToString().Contains(str) || PathID.ToString().Contains(str) || PathIDType.ToString().Contains(str) || PatrolType.ToString().Contains(str) || SpeedType.ToString().Contains(str)) { return(true); } else { return(false); } }
public List <Vector3> GetPatrolWaypoints(PatrolType pt, Vector3 dir, float maxDist) { List <Vector3> vector3List = new List <Vector3>(); float num1 = Math.Min(this.m_MaxRadius - this.m_MinRadius, maxDist); Vector3 vector3_1 = this.m_Destination + dir * this.m_MinRadius; Vector3 vector3_2 = Vector3.Cross(dir, Vector3.UnitY); switch (pt) { case PatrolType.Circular: float num2 = num1 * 0.5f; Vector3 vector3_3 = vector3_1 + dir * num2; int num3 = 8; float radians1 = MathHelper.DegreesToRadians(360f / (float)num3); for (int index = 0; index < num3; ++index) { float num4 = radians1 * (float)index; Vector3 vector3_4 = new Vector3((float)Math.Sin((double)num4), 0.0f, -(float)Math.Cos((double)num4)); vector3List.Add(vector3_3 + vector3_4 * num2); } break; case PatrolType.Line: float num5 = 1000f; Vector3 vector3_5 = vector3_1 + dir * num5; vector3List.Add(vector3_5 + vector3_2 * num1); vector3List.Add(vector3_5 - vector3_2 * num1); break; case PatrolType.Box: vector3List.Add(this.m_Destination + dir * this.m_MaxRadius + vector3_2 * num1); vector3List.Add(this.m_Destination + dir * this.m_MaxRadius - vector3_2 * num1); vector3List.Add(this.m_Destination + dir * this.m_MinRadius + vector3_2 * num1); vector3List.Add(this.m_Destination + dir * this.m_MinRadius - vector3_2 * num1); break; case PatrolType.Orbit: float num6 = 1000f; int num7 = 8; float radians2 = MathHelper.DegreesToRadians(360f / (float)num7); for (int index = 0; index < num7; ++index) { float num4 = radians2 * (float)index; Vector3 vector3_4 = new Vector3((float)Math.Sin((double)num4), 0.0f, -(float)Math.Cos((double)num4)); vector3List.Add(this.m_Destination + vector3_4 * (this.m_MinRadius + num6)); } break; } return(vector3List); }
/// <summary> /// Constructor /// </summary> public PatrolEnemy(String image, Vector2 position, Vector2 size, int rowCounts, int columnCount, int padding) : base(image, position, size, rowCounts, columnCount, padding) { // causes update state to always change into a new state mTargetPosition = Position = Vector2.Zero; Velocity = Vector2.UnitY; mTintColor = kPatrolTint; mCurrentPatrolType = PatrolType.FreeRoam; Position = RandomPosition(true); mDestoryFlag = false; mAllowRotate = false; SetSpriteAnimation(0, 0, 1, 1, 10); FishSize = kInitFishSize; mCurrentEnemyType = EnemyType.BlowFish; }
/// <summary> /// Initializes a generic patrol pattern /// </summary> /// <param name="enemy">Reference to the enemy that the AI is controlling</param> /// <param name="patrolType">Pattern of movement</param> public AI(Enemy enemy, PatrolType patrolType) { this.enemy = enemy; this.patrolType = patrolType; patrolState = PatrolState.PauseRight; facingRight = true; walkSpeed = 3.0; frameCounter = 0; // Pauses for 2 seconds on each side by default pauseLeft = 120; pauseRight = 120; // Initializes variables used for locking a finite state stunnedFrames = 0; }
/// <summary> /// Creates a generic Enemy /// </summary> /// <param name="x">X location of the </param> /// <param name="y"></param> /// <param name="node">Reference to the quad tree used in-game</param> /// <param name="patrolType"></param> public Enemy(int x, int y, QuadTreeNode node, PatrolType patrolType) // Defaults to a width of 64 and a height of 128 : base(x, y, 64, 128, node) { // Initialize the AI pattern mainAi = new AI(this, patrolType); HP = 30; // Initialize hitbox parameters Position = new Vector2(X, Y); Size = new Vector2(64, 128); noClip = false; // Initialize animation parameters currentFrame = 0; secondsPerFrame = 1.0f / 30.0f; }
/* * Animator values * trigger "Attacked" - When the AI Attacks * bool "Idle" - Is in the Idle state * bool "Patroling" - Is in the patroling state * bool "Wandering" - Is in the Wandering State * bool "Aggressive" - Is in the aggressive state * trigger "Healed" - When the AI is healed * trigger "Damaged" - when the AI is damaged * bool "IsImmune" - Is immune to damage * bool "IsStunned" - If the AI is stunned * float "MoveDirection" - Direction of Movement (-1 for left, 1 for right, 0 for not moving) */ // Start is called before the first frame update void Start() { ComponentDoubleCheck(); _InitalLocation = transform.position; _RandomWanderSpot = new Vector2(Random.Range(-_WanderRange.x, _WanderRange.x) + _InitalLocation.x, Random.Range(-_WanderRange.y, _InitalLocation.y) + _InitalLocation.y); if (_State == AiState.Patroling) { if (_MoveSpots != null) { _NumOfSpots = _MoveSpots.Length; } if (_NumOfSpots <= 0) { _PatrolType = PatrolType.Idle; } } }
/// <summary> /// Add a new patrol area and specify target names /// </summary> /// <param name="name">The name of the new patrol area</param> /// <param name="targetNames">An ArrayList containing the names of targets for this new patrol area</param> /// <param name="type">A PatrolType indicating what type of list this is</param> public void AddPatrolArea(string name, ArrayList targetNames, PatrolType type) { if (name == "") { throw new Exception("You must specify a name for a new PatrolArea!"); } lock (_mPatrolAreas.SyncRoot) { if (_mPatrolAreas.ContainsKey(name)) { throw new Exception("Patrol Area " + name + " already exists!"); } _mPatrolAreas.Add(name, new PatrolArea(_ak, targetNames, type, name)); } }
public PatrolShipControl( App game, TacticalObjective to, CombatAI commanderAI, PatrolType pt, Vector3 dir, float maxPatrolDist, bool clockwise) : base(game, to, commanderAI) { this.m_Type = ShipControlType.Patrol; this.m_PatrolType = pt; this.m_ClockWise = clockwise; this.m_PrevPosition = new Vector3(); this.m_PrevDir = new Vector3(); this.m_StuckDelay = PatrolShipControl.kStuckDelay; this.ResetPatrolWaypoints(pt, dir, maxPatrolDist); this.m_CloseToDist = 1000f; }
void Start() { if (waypoints.Length > 1) { foreach (Transform go in waypoints) { go.parent = null; } } stat = GetComponent <Status>(); ai = GetComponent <AIenemy>(); mainModel = stat.mainModel; useMecanim = ai.useMecanim; if (!mainModel) { mainModel = this.gameObject; } movingAnimation = ai.movingAnimation; idleAnimation = ai.idleAnimation; if (!mainModel) { mainModel = this.gameObject; } if (waypoints.Length <= 0 && movement != PatrolType.RandomPatrol) { movement = PatrolType.RandomPatrol; } //-------Check for Mecanim Animator----------- if (useMecanim) { animator = ai.animator; if (!animator) { animator = mainModel.GetComponent <Animator>(); } } }
public void ResetPatrolWaypoints(PatrolType pt, Vector3 dir, float maxPatrolDist) { if (!(this.m_TaskGroupObjective is PatrolObjective)) { return; } this.m_PatrolWaypoints = (this.m_TaskGroupObjective as PatrolObjective).GetPatrolWaypoints(pt, dir, maxPatrolDist); this.m_PrevDir = dir; Vector3 currentPosition = this.GetCurrentPosition(); this.m_CurrWaypointIndex = 0; float num = float.MaxValue; for (int index = 0; index < this.m_PatrolWaypoints.Count; ++index) { float lengthSquared = (this.m_PatrolWaypoints[index] - currentPosition).LengthSquared; if ((double)lengthSquared < (double)num) { num = lengthSquared; this.m_CurrWaypointIndex = index; } } }
public EnemyMoveAI(float speed, PatrolType patrolType) { _speed = speed; PatrolType = patrolType; _frequency = 200; }
void DoPatrol() { if (mNPC.mRefreshList == null) { return; } int npcAIID = mNPC.mRefreshList.npcAI; excel_npc_ai npcAI = excel_npc_ai.Find(npcAIID); if (npcAI == null) { return; } if (NormalBehaviourPhase.PatrolInterval == mPhase) { mIntervalTime -= Time.DeltaTime; if (mIntervalTime > 0.0f) { return; } PatrolType patrolType = (PatrolType)npcAI.patrolType; if (patrolType == PatrolType.Scope) { if (mNPC.mRefreshList.birthpoint.Length <= 0) { return; } string birthpoint = mNPC.mRefreshList.birthpoint[0]; MarkPoint markPoint = RefreshSystem.Instance.GetMarkPoint(mNPC.mScene.ScnID, birthpoint); if (markPoint == null) { return; } Vector3 targetPos = markPoint.position; Vector3 dir = new Vector3(Mathf.RandRange(-1.0f, 1.0f), 0.0f, Mathf.RandRange(-1.0f, 1.0f)); dir.Normalize(); float dist = Mathf.RandRange(0.0f, 1.0f) * npcAI.patrolRadius; targetPos += (dist * dir); Vector3 hitPos = Vector3.zero; if (NavigationSystem.LineCast(mNPC.Position, targetPos, mNPC.mNavLayer, out hitPos)) { targetPos = hitPos; } mPath = new Vector3[1]; mPath[0] = targetPos; mPathIndex = 0; mPhase = NormalBehaviourPhase.Patrol; } } else if (NormalBehaviourPhase.Patrol == mPhase) { if (mPath == null || mPathIndex >= mPath.Length) { mIntervalTime = Mathf.RandRange(npcAI.patrolMinInterval, npcAI.patrolMaxInterval); mPhase = NormalBehaviourPhase.PatrolInterval; return; } Vector3 targetPos = mPath[mPathIndex]; if (!mNPC.IsSearchMoving()) { mNPC.SearchMove(targetPos); } float dist = (targetPos - mNPC.Position).Length(); if (dist <= 0.3f) { ++mPathIndex; } } }
void Update() { if (freeze || stat.freeze) { return; } if (ai.followState == AIState.Idle) { if (state >= 1) //Moving { CharacterController controller = GetComponent <CharacterController>(); Vector3 forward = transform.TransformDirection(Vector3.forward); controller.Move(forward * speed * Time.deltaTime); if (movingAnimation && !useMecanim) { //For Legacy Animation mainModel.GetComponent <Animation>().CrossFade(movingAnimation.name, 0.2f); } else if (useMecanim) { //For Mecanim Animation animator.SetBool("run", true); } } //---------------------------- if (wait >= waitDuration && state == 0) { if (movement != PatrolType.RandomPatrol) { //Set to Moving Mode. if (movement == PatrolType.WaypointRandom) { RandomWaypoint(); } else { WaypointStep(); } } else { //Set to Moving Mode. RandomTurning(); } } //------------------------------------- if (wait >= waitDuration && state == 1) { //Set to Idle Mode. if (idleAnimation && !useMecanim) { //For Legacy Animation mainModel.GetComponent <Animation>().CrossFade(idleAnimation.name, 0.2f); } else if (useMecanim) { //For Mecanim Animation animator.SetBool("run", false); } wait = 0; waitDuration = Random.Range(idleDuration.x, idleDuration.y); state = 0; } //---------------------------------------- if (state == 2) { Vector3 destination = headToPoint.position; destination.y = transform.position.y; transform.LookAt(destination); distance = (transform.position - GetDestination()).magnitude; if (distance <= 0.2f) { //Set to Idle Mode. if (idleAnimation && !useMecanim) { //For Legacy Animation mainModel.GetComponent <Animation>().CrossFade(idleAnimation.name, 0.2f); } else if (useMecanim) { //For Mecanim Animation animator.SetBool("run", false); } wait = 0; waitDuration = Random.Range(idleDuration.x, idleDuration.y); state = 0; } else if (Time.time > moveEnough) { //If this enemy cannot reach the waypoint in time. //Set to Idle Mode. if (idleAnimation && !useMecanim) { //For Legacy Animation mainModel.GetComponent <Animation>().CrossFade(idleAnimation.name, 0.2f); } else if (useMecanim) { //For Mecanim Animation animator.SetBool("run", false); } wait = 0; waitDuration = Random.Range(idleDuration.x, idleDuration.y); state = 0; //Reset the Movement type to Random movement = PatrolType.RandomPatrol; } } wait += Time.deltaTime; //----------------------------- } }
private void OnGUI() { // --- GUI Styles --- GUIStyle textStyle1 = new GUIStyle(); textStyle1.fontSize = 12; textStyle1.fontStyle = FontStyle.Italic; GUIStyle title = new GUIStyle(); title.fontSize = 14; title.fontStyle = FontStyle.Bold; GUIStyle boldText = new GUIStyle(); boldText.margin.left = 3; boldText.fontStyle = FontStyle.Bold; // --- --- // --- Introduction! --- EditorGUILayout.Space(); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (createOrModify == CreateOrModify.modify) { GUILayout.Label("Character Modification", title); } else { GUILayout.Label("Character Creation", title); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); EditorGUILayout.Space(); // --- --- EditorGUI.BeginChangeCheck(); createOrModify = (CreateOrModify)EditorGUILayout.EnumPopup("Create or Modify", createOrModify); if (createOrModify == CreateOrModify.create && EditorGUI.EndChangeCheck()) { ResetCreationData(); } if (createOrModify == CreateOrModify.create) { modifyCharacter.target = false; } else { modifyCharacter.target = true; } if (EditorGUILayout.BeginFadeGroup(modifyCharacter.faded)) { EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); characterToModify = EditorGUILayout.ObjectField("Character to modify", characterToModify, typeof(GameObject), true) as GameObject; if (characterToModify != null && EditorGUI.EndChangeCheck()) { FillModifyData(); } EditorGUI.indentLevel--; } EditorGUILayout.EndFadeGroup(); DrawHorizontalUILine(Color.gray, 1, 4, 45); EditorGUILayout.Space(); // --- Character centered information --- GUILayout.Label("Character Information", boldText); characterName = EditorGUILayout.TextField(new GUIContent("Character Name"), characterName); characterLayer = EditorGUILayout.LayerField(new GUIContent("Layer for the character", "This is optional but reccomended"), characterLayer); characterTag = EditorGUILayout.TagField(new GUIContent("Tag for the character", "This is optional but reccomended"), characterTag); maxHealth = EditorGUILayout.IntField(new GUIContent("Max health", "Will default to 100"), maxHealth); // --- --- // --- Logic centered information --- if (createOrModify == CreateOrModify.create) { playerOrNPC = (PlayerOrNPC)EditorGUILayout.EnumPopup("Player or NPC", playerOrNPC); } if (playerOrNPC == PlayerOrNPC.player) { showNPCCenteredInfo.target = false; showPlayerCenteredInfo.target = true; } else { showNPCCenteredInfo.target = true; showPlayerCenteredInfo.target = false; } // --- Player centered logic --- if (EditorGUILayout.BeginFadeGroup(showPlayerCenteredInfo.faded)) { DrawHorizontalUILine(Color.gray, 1, 4, 45); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Player centered logic", textStyle1); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); EditorGUI.indentLevel++; movementType = (MovementType)EditorGUILayout.EnumPopup("Movement Type", movementType); EditorGUI.indentLevel--; DrawHorizontalUILine(Color.gray, 1, 4, 45); } EditorGUILayout.EndFadeGroup(); // --- // --- NPC centered Logic --- if (EditorGUILayout.BeginFadeGroup(showNPCCenteredInfo.faded)) { DrawHorizontalUILine(Color.gray, 1, 4, 45); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("NPC centered logic", textStyle1); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); EditorGUI.indentLevel++; //As Friendly NPC Logic is not implemented, we will not allow for this for now and will instead just set friendOrFoe to enemy. //friendOrFoe = (FriendOrFoe)EditorGUILayout.EnumPopup("Friendly or Enemy", friendOrFoe); friendOrFoe = FriendOrFoe.enemy; // This will be fixed by removing the friendOrFoe = enemy and uncommenting the line above it when friendly Logic has been implemented if (friendOrFoe == FriendOrFoe.enemy) { patrolType = (PatrolType)EditorGUILayout.EnumPopup("Patrol Type", patrolType); patrolObject = EditorGUILayout.ObjectField(new GUIContent("Patrol object", "If patrol type != 'Roam', this is the parent object and will need the patrol points childed. If it is, this will be the center of the roam patrol"), patrolObject, typeof(Transform), true) as Transform; if (patrolType == PatrolType.roam) { roaming.target = true; } else { roaming.target = false; } if (EditorGUILayout.BeginFadeGroup(roaming.faded)) { EditorGUI.indentLevel++; roamRadius = EditorGUILayout.FloatField(new GUIContent("Radius", "The radius of the roam patrol type"), roamRadius); EditorGUI.indentLevel--; } EditorGUILayout.EndFadeGroup(); } else { EditorGUILayout.HelpBox("Friendly NPC behaviour has not been implemented yet, and will be coming shortly", MessageType.Info); } attackRange = EditorGUILayout.FloatField(new GUIContent("Attack range", "The range an enemy will need to be from the player to start attacking. It is defaulted to 5 because of the reach of the attack"), attackRange); EditorGUI.indentLevel--; DrawHorizontalUILine(Color.gray, 1, 4, 45); } EditorGUILayout.EndFadeGroup(); // --- EditorGUILayout.Space(); baseSpeed = EditorGUILayout.Slider(new GUIContent("Base speed", "Base speed before any modification. This is in units traveled per second"), baseSpeed, 3.5f, 15f); // --- --- // --- Advanced character information --- advancedCharacterInfo = EditorGUILayout.Foldout(advancedCharacterInfo, "Advanced character info", true); if (advancedCharacterInfo) { EditorGUI.indentLevel++; if (createOrModify != CreateOrModify.modify) { appendIDToName.target = EditorGUILayout.ToggleLeft(new GUIContent("Append ID to Name", "Appends a nummerical ID to the end of the name"), appendIDToName.target); if (EditorGUILayout.BeginFadeGroup(appendIDToName.faded)) { EditorGUI.indentLevel++; characterID = EditorGUILayout.IntField("Character ID", characterID); EditorGUI.indentLevel--; DrawHorizontalUILine(Color.gray, 1, 4, 45); } EditorGUILayout.EndFadeGroup(); } shouldUseFieldOfView.target = EditorGUILayout.ToggleLeft("Use Field Of View", shouldUseFieldOfView.target); if (EditorGUILayout.BeginFadeGroup(shouldUseFieldOfView.faded)) { EditorGUI.indentLevel++; fieldOfViewMat = EditorGUILayout.ObjectField("Material for the FOW", fieldOfViewMat, typeof(Material), false) as Material; obstacleLayer = EditorGUILayout.LayerField(new GUIContent("Obstacle layer", "Sets the layer for obstacles for the FOW"), obstacleLayer); targetLayer = EditorGUILayout.LayerField(new GUIContent("Target layer", "Sets the layer for targets for the FOW"), targetLayer); fieldOfViewRadius = EditorGUILayout.IntField(new GUIContent("Field of view radius", "The radius of the field of view"), fieldOfViewRadius); if (fieldOfViewRadius < 0) { fieldOfViewRadius = 0; } fieldOfViewAngle = EditorGUILayout.IntSlider(new GUIContent("Field of view angle", "The angle of the field of view"), fieldOfViewAngle, 0, 360); EditorGUI.indentLevel--; } EditorGUILayout.EndFadeGroup(); EditorGUI.indentLevel--; } // --- DrawHorizontalUILine(Color.gray); // --- --- EditorGUILayout.Space(); // --- Object centered basic information --- GUILayout.Label("Basic Object information", boldText); //GUILayout.Box("FOO", GUILayout.ExpandWidth(true)); characterModel = EditorGUILayout.ObjectField("Character Model:", characterModel, typeof(GameObject), true) as GameObject; // --- Advanced object info --- advancedObjectInfo = EditorGUILayout.Foldout(advancedObjectInfo, "Advanced object info", true); if (advancedObjectInfo) { EditorGUI.indentLevel++; if (createOrModify != CreateOrModify.modify) { modelUsesEmptyParent = EditorGUILayout.ToggleLeft(new GUIContent("Model uses empty parent", "Will not child the model to an empty Game Object"), modelUsesEmptyParent); useSpecifiedParent.target = EditorGUILayout.ToggleLeft(new GUIContent("Use specified parent object", "will use specified Game Object as parent"), useSpecifiedParent.target); if (EditorGUILayout.BeginFadeGroup(useSpecifiedParent.faded)) { specifiedParent = EditorGUILayout.ObjectField(new GUIContent("Parent Object", "This needs to be a scene object"), specifiedParent, typeof(Transform), true) as Transform; } else { specifiedParent = null; } EditorGUILayout.EndFadeGroup(); } useSpecifiedTransformForHands.target = EditorGUILayout.ToggleLeft(new GUIContent("Use specified transform for hands"), useSpecifiedTransformForHands.target); if (EditorGUILayout.BeginFadeGroup(useSpecifiedTransformForHands.faded)) { mainHand = EditorGUILayout.ObjectField(new GUIContent("Main hand transform", "If left empty, the tool will create one at position 0.75,0.75,0"), mainHand, typeof(Transform), true) as Transform; offHand = EditorGUILayout.ObjectField(new GUIContent("Off hand transform", "If left empty, the tool will create one at position -0.75,0.75,0"), offHand, typeof(Transform), true) as Transform; } EditorGUILayout.EndFadeGroup(); if (useSpecifiedTransformForHands.value == false) { usesNameForFindingHands.target = true; } else { usesNameForFindingHands.target = false; } if (EditorGUILayout.BeginFadeGroup(usesNameForFindingHands.faded)) { mainHandName = EditorGUILayout.TextField(new GUIContent("Main hand name in model", "If left empty, or object cannot be found, the tool will create one at position 0.75,0.75,0"), mainHandName); offHandName = EditorGUILayout.TextField(new GUIContent("Off hand name in model", "if left empty, or object cannot be found, the tool will create one at position -0.75,0.75,0"), offHandName); } EditorGUILayout.EndFadeGroup(); attackPoint = EditorGUILayout.ObjectField(new GUIContent("Attack point", "This is the point where an attack is calculated around. It is implemented because of the way the system currently works. If left empty, the tool will create one at position 0,1,2"), attackPoint, typeof(Transform), true) as Transform; //CreateFadeGroup<Transform>(useSpecifiedParent, "Use specified parent object", specifiedParent, "parent object"); EditorGUI.indentLevel--; } // --- DrawHorizontalUILine(Color.gray); EditorGUILayout.Space(); // --- --- // --- Do you want a prefab with that? --- if (createOrModify != CreateOrModify.modify) { GUILayout.Label("Prefab information", boldText); createPrefab.target = EditorGUILayout.ToggleLeft("Save as a Prefab", createPrefab.target); if (EditorGUILayout.BeginFadeGroup(createPrefab.faded)) { EditorGUI.indentLevel++; prefabPath = EditorGUILayout.TextField("Prefab Path", prefabPath == string.Empty ? "'Assets/SomeFolder...'" : prefabPath); doCreatePrefab = true; keepInScene = EditorGUILayout.ToggleLeft("Keep in scene?", keepInScene); EditorGUI.indentLevel--; } else { doCreatePrefab = false; keepInScene = false; } EditorGUILayout.EndFadeGroup(); DrawHorizontalUILine(Color.gray); EditorGUILayout.Space(); } // --- --- // --- Animation stuff --- GUILayout.Label("Animator information", boldText); animator = EditorGUILayout.ObjectField(new GUIContent("Animator controller"), animator, typeof(RuntimeAnimatorController), false) as RuntimeAnimatorController; //animator = EditorGUILayout.PropertyField(new GUIContent("Animator goes here"), animator, typeof(RuntimeAnimatorController)) as RuntimeAnimatorController; //EditorGUILayout.fiel // --- --- // --- Creation/Modification button --- if (createOrModify == CreateOrModify.create) { EditorGUI.BeginDisabledGroup(createButtonDisableParams()); if (GUILayout.Button("Create Character")) { CreateCharacter(); } EditorGUI.EndDisabledGroup(); } else { EditorGUI.BeginDisabledGroup(createButtonDisableParams()); if (GUILayout.Button("Modify Character")) { ModifyCharacter(); } EditorGUI.EndDisabledGroup(); } EditorGUILayout.Space(); // --- --- //Stuff for errors here.. // --- Error messages --- // Modify stuff if (modifyCharacter.value == true && characterToModify == null) { EditorGUILayout.HelpBox("Please insert character to modify", MessageType.Warning); } if (modifyCharacter.value == true && characterToModify != null && characterName == string.Empty) { EditorGUILayout.HelpBox("Please give a Name to the Character", MessageType.Warning); } // --- // Create stuff if (characterName == string.Empty && modifyCharacter.value == false) { EditorGUILayout.HelpBox("Please give a Name to the Character", MessageType.Warning); } if (characterModel == null && !modifyCharacter.value == true) { EditorGUILayout.HelpBox("Please insert Character Model", MessageType.Warning); } if (playerOrNPC == PlayerOrNPC.NPC && patrolObject == null) { EditorGUILayout.HelpBox("Please insert a patrol object", MessageType.Warning); } if (shouldUseFieldOfView.value == true && fieldOfViewMat == null) { EditorGUILayout.HelpBox("Please supply a material for the field of view", MessageType.Warning); } if (shouldUseFieldOfView.value == true && obstacleLayer == LayerMask.NameToLayer("Default")) { EditorGUILayout.HelpBox("Obstacle layer should not be default", MessageType.Warning); } if (shouldUseFieldOfView.value == true && targetLayer == LayerMask.NameToLayer("Default")) { EditorGUILayout.HelpBox("Target layer should not be default", MessageType.Warning); } if (useSpecifiedParent.value == true && specifiedParent == null) { EditorGUILayout.HelpBox("Please supply a parent object", MessageType.Warning); } if (useSpecifiedParent.value == true && specifiedParent != null && EditorUtility.IsPersistent(specifiedParent)) { EditorGUILayout.HelpBox("Specified parent object needs to be a scene object", MessageType.Warning); } if (createPrefab.value == true && prefabPath == "'Assets/SomeFolder...'") { EditorGUILayout.HelpBox("Please insert a valid path name for your prefab", MessageType.Warning); } // --- // --- --- }
//Handle movement depending on PatrolSate and AttackMode void MovementManager() { //If the AI sees or hears the target if (canHear || targetInSight) { if (targetInSight) { RotateTurret(); Fire(); } if (canHear) { RotateTurret(); } //Keep track of time gameTime = Time.time; //This will be the targets current position //for as long as the target is seen lastSeenLocation = target.position; //Get the current states before setting the new ones //and wait until the AI isn't searching in order to set it again //This is preventing the lastPatrolType and lastAttackMode //from being overwritten every frame if (searching == false && attackMode != AttackMode.Idle) { //Store the last states lastPatrolType = currentPatrolType; lastAttackMode = attackMode; //And make the AI stop looking for waypoints to move towards currentPatrolType = PatrolType.Idle; //Debug.Log("Hear"); //The AI is now set to search for the target if it loses track searching = true; } //If the AI's low on health and it's not currently in the flee state //set it to the flee State if (currentHealth <= healthToFlee && attackMode != AttackMode.Flee) { attackMode = AttackMode.Flee; } //If the AI is searching and it finds the target //Stop searching and put it in its lastAttackMode if (attackMode == AttackMode.Searching) { attackMode = lastAttackMode; } if (attackMode == AttackMode.Chase) { Chase(); } if (attackMode == AttackMode.Flee) { Flee(); } if (attackMode == AttackMode.Idle) { Patrol(); } } //If AI cant see or hear target else if (!canHear && !targetInSight) { //If it's time for the AI to search and it isnt trying to to run away if (searching == true && Time.time < gameTime + searchTime && attackMode != AttackMode.Flee && attackMode != AttackMode.Idle) { attackMode = AttackMode.Searching; } else if (searching == true && Time.time > gameTime + searchTime) { //Give the AI its previous settings searching = false; attackMode = lastAttackMode; currentPatrolType = lastPatrolType; //Debug.Log("lost track"); } if (attackMode == AttackMode.Searching) { Search(); } //Go back to patrolling Patrol(); } }
/// <summary> /// Load all PatrolAreas /// </summary> /// <remarks> /// PatrolAreas are stored at: /// [ExecutablePath]\PatrolAreas\[PatrolArea].xml /// </remarks> public void LoadPatrolAreas( ) { // create NumberFormatInfo object for converting string to float NumberFormatInfo nfi = new NumberFormatInfo(); nfi.NumberGroupSeparator = ","; nfi.NumberDecimalSeparator = "."; //get path string directory = Path.GetDirectoryName(Application.ExecutablePath); if (!directory.EndsWith("\\")) { directory += "\\"; } directory += "PatrolAreas"; if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } //get all files string[] patrolareaFiles = Directory.GetFiles(directory, "*.xml"); lock (_mPatrolAreas.SyncRoot) { //get rid of any old entries _mPatrolAreas.Clear(); //process each file foreach (string filename in patrolareaFiles) { XmlDocument doc = new XmlDocument(); doc.Load(filename); XmlNode root = doc.DocumentElement; IEnumerator eachPatrolArea = root.GetEnumerator(); XmlNode patrolarea; while (eachPatrolArea.MoveNext()) { patrolarea = (XmlNode)eachPatrolArea.Current; //create a new PatrolArea object using the name from the root string paName = patrolarea.Attributes.GetNamedItem("Name").Value; if (paName == "") { continue; } PatrolType type = (PatrolType)Enum.Parse(typeof(PatrolType), patrolarea.Attributes.GetNamedItem("Type").Value); AddPatrolArea(paName, type); IEnumerator eachPatrolAreaElement = patrolarea.GetEnumerator(); XmlNode patrolareaElement; while (eachPatrolAreaElement.MoveNext()) { patrolareaElement = (XmlNode)eachPatrolAreaElement.Current; if (patrolareaElement.Name == "Target") { GetPatrolArea(paName).AddTarget(patrolareaElement.Attributes.GetNamedItem("Name").Value); } if (patrolareaElement.Name == "Waypoint") { GetPatrolArea(paName).AddWaypoint(float.Parse(patrolareaElement.Attributes.GetNamedItem("X").Value, nfi), float.Parse(patrolareaElement.Attributes.GetNamedItem("Y").Value, nfi), float.Parse(patrolareaElement.Attributes.GetNamedItem("Z").Value, nfi), patrolareaElement.Attributes.GetNamedItem("PointName").Value); } } } } } }
void FillModifyData() { characterName = characterToModify.name; characterLayer = characterToModify.layer; characterTag = characterToModify.tag; if (characterToModify.GetComponent <Player_CharacterController>() != null) { playerOrNPC = PlayerOrNPC.player; if (characterToModify.GetComponent <Player_CharacterController>().clickToMove) { movementType = MovementType.ClickToMove; } else { movementType = MovementType.WASD; } } if (characterToModify.GetComponent <NPC_CharacterController>() != null) { playerOrNPC = PlayerOrNPC.NPC; if (characterToModify.GetComponent <NPC_CharacterController>().friendOrFoe == NPC_CharacterController.FriendOrFoe.enemy) { friendOrFoe = FriendOrFoe.enemy; if (characterToModify.GetComponent <NPC_CharacterController>().patrolType == State_Patrol.PatrolType.Circular) { patrolType = PatrolType.circular; } if (characterToModify.GetComponent <NPC_CharacterController>().patrolType == State_Patrol.PatrolType.ForthAndBack) { patrolType = PatrolType.forthAndBack; } if (characterToModify.GetComponent <NPC_CharacterController>().patrolType == State_Patrol.PatrolType.Roam) { patrolType = PatrolType.roam; } patrolObject = characterToModify.GetComponent <NPC_CharacterController>().patrolPointsObject.transform; attackRange = characterToModify.GetComponent <Character>().attackRange; } else { friendOrFoe = FriendOrFoe.friendly; } } if (characterToModify.GetComponent <Animator>().runtimeAnimatorController != null) { animator = characterToModify.GetComponent <Animator>().runtimeAnimatorController; } if (characterToModify.GetComponent <Character>().mainHand != null) { useSpecifiedTransformForHands.target = true; mainHand = characterToModify.GetComponent <Character>().mainHand; } if (characterToModify.GetComponent <Character>().offHand != null) { useSpecifiedTransformForHands.target = true; offHand = characterToModify.GetComponent <Character>().offHand; } if (characterToModify.GetComponent <Character>().attackPoint != null) { attackPoint = characterToModify.GetComponent <Character>().attackPoint; } baseSpeed = characterToModify.GetComponent <Character>().baseSpeed; if (characterToModify.GetComponent <Player_CharacterController>() != null && characterToModify.GetComponent <Player_CharacterController>().usesFieldOfView || characterToModify.GetComponent <NPC_CharacterController>() != null && characterToModify.GetComponent <NPC_CharacterController>().usesFieldOfView) { shouldUseFieldOfView.target = true; if (playerOrNPC == PlayerOrNPC.player) { fieldOfViewMat = characterToModify.GetComponent <Player_CharacterController>().filter.gameObject.GetComponent <MeshRenderer>().sharedMaterial; //Some way to get the obstacle and target layer here obstacleLayer = Mathf.RoundToInt(Mathf.Log(characterToModify.GetComponent <Player_CharacterController>().obstacleAndTargetMasks[0].value, 2)); targetLayer = Mathf.RoundToInt(Mathf.Log(characterToModify.GetComponent <Player_CharacterController>().obstacleAndTargetMasks[1].value, 2)); fieldOfViewRadius = Mathf.RoundToInt(characterToModify.GetComponent <Player_CharacterController>().viewRadiusAnglesResolution.x); fieldOfViewAngle = Mathf.RoundToInt(characterToModify.GetComponent <Player_CharacterController>().viewRadiusAnglesResolution.y); } else { fieldOfViewMat = characterToModify.GetComponent <NPC_CharacterController>().fowFilter.gameObject.GetComponent <MeshRenderer>().sharedMaterial; //Some way to get the obstacle and target layer here obstacleLayer = Mathf.RoundToInt(Mathf.Log(characterToModify.GetComponent <NPC_CharacterController>().obstaclesAndTargetMasks[0].value, 2)); targetLayer = Mathf.RoundToInt(Mathf.Log(characterToModify.GetComponent <NPC_CharacterController>().obstaclesAndTargetMasks[1].value, 2)); fieldOfViewRadius = Mathf.RoundToInt(characterToModify.GetComponent <NPC_CharacterController>().viewRadiusAnglesResolution.x); fieldOfViewAngle = Mathf.RoundToInt(characterToModify.GetComponent <NPC_CharacterController>().viewRadiusAnglesResolution.y); } } foreach (Transform transform in characterToModify.GetComponentInChildren <Transform>()) { if (transform.gameObject.name == "CharacterModel") { characterModel = transform.gameObject; } } }
void Patrol() { float distToPlayer = Vector3.Distance(transform.position, player.transform.position); if (distToPlayer <= detectDistance) { if (Physics.Linecast(transform.position, player.transform.position, out RaycastHit hit)) { if (hit.collider.CompareTag("Player")) { if (patrolType != PatrolType.CHASE) { patrolType = PatrolType.DETECT; } } } } switch (patrolType) { case PatrolType.CHASE: agent.SetDestination(player.transform.position); if (distToPlayer > detectDistance) { patrolType = PatrolType.DETECT; } break; case PatrolType.DETECT: agent.SetDestination(transform.position); undetectTimer -= Time.deltaTime; if (undetectTimer <= 0) { if (distToPlayer <= detectDistance) { patrolType = PatrolType.CHASE; undetectTimer = 5; } else { patrolType = PatrolType.RANDOM; agent.SetDestination(waypoints[currentWaypoint].transform.position); } } break; default: float dist = Vector3.Distance(transform.position, waypoints[currentWaypoint].transform.position); if (dist < 0.1f) { if (patrolType == PatrolType.LINEAR) { currentWaypoint = currentWaypoint < waypoints.Count - 1 ? currentWaypoint += 1 : 0; } else { currentWaypoint = Random.Range(0, waypoints.Count); } agent.SetDestination(waypoints[currentWaypoint].transform.position); } undetectTimer = 5; break; } }
public void SetNewPatrolDestination(PatrolType Type_Patrol) { int Random_num; Transform[] WayPoints; target = null; if (Type_Patrol == PatrolType.Patrol || Type_Patrol == PatrolType.Fixed) { WayPoints = patrolWayPoints; } else if ((Type_Patrol == PatrolType.Panic || Type_Patrol == PatrolType.Idle) && panicWayPoints.Length > 0) { WayPoints = panicWayPoints; } else { if (patrolWayPoints.Length > 0) { WayPoints = patrolWayPoints; } else { _nav.destination = this.transform.position; return; } } if (Type_Patrol == PatrolType.Fixed) { wayPointIndex++; if (wayPointIndex >= WayPoints.Length) { wayPointIndex = 0; } } else { Random_num = rnd.Next(0, WayPoints.Length); while (Random_num == wayPointIndex && WayPoints.Length > 0) { Random_num = rnd.Next(0, WayPoints.Length); } wayPointIndex = Random_num; } if (WayPoints.Length == 0) { _nav.destination = this.transform.position; } else { _nav.destination = WayPoints[wayPointIndex].position; } //Debug.Log(transform.name + " going to Target: " + (WayPoints[wayPointIndex].name)); }
/// <summary> /// Updates the enemy's movement AI by 1 frame and returns the change in X position /// Called through a class property /// </summary> public void MoveAI() { enemy.State = UpdateAggro(); // Update the current finite state switch (enemy.State) { case EnemyState.Docile: // Check to see whether something causes the enemy to leave a Docile state // Make normal Docile movement patterns if the enemy's still docile switch (patrolState) { case PatrolState.WalkLeft: patrolType = PatrolType.Moving; // If the enemy is unable to walk to the left, update to PauseLeft if (!AbleToMove()) { // If the enemy never pauses facing to the left, swap immediately to walking right if (pauseLeft > 0) { frameCounter = 0; patrolState = PatrolState.PauseLeft; } else { patrolState = PatrolState.WalkRight; facingRight = true; } } break; case PatrolState.PauseLeft: patrolType = PatrolType.Standing; // If the enemy has stood still for pauseLeft frames, walk right if (++frameCounter >= pauseLeft) { patrolState = PatrolState.WalkRight; facingRight = true; } break; case PatrolState.WalkRight: patrolType = PatrolType.Moving; if (!AbleToMove()) { // If the enemy never pauses facing to the right, swap immediately to walking left if (pauseRight > 0) { frameCounter = 0; patrolState = PatrolState.PauseRight; } else { patrolState = PatrolState.WalkLeft; facingRight = false; } } break; case PatrolState.PauseRight: patrolType = PatrolType.Standing; // If the enemy has stood still for pauseRight frames, walk left if (++frameCounter >= pauseRight) { patrolState = PatrolState.WalkLeft; facingRight = false; } break; default: throw new NotImplementedException("Unknown PatrolState case in AI.MoveAI()"); } break; // If the enemy has been stunned for the number of frames, unstun them and return to docile // TODO: Update this to involve swapping to aggro case EnemyState.Damaged: if (stunnedFrames == 0) { enemy.State = EnemyState.Docile; } else { stunnedFrames--; } break; default: break; } // Move based off the current state switch (enemy.State) { // If the enemy is docile, follow the patrol route case EnemyState.Docile: switch (patrolState) { case PatrolState.PauseLeft: case PatrolState.PauseRight: { enemy.Movement = new Vector2(0f, enemy.Movement.Y); break; } case PatrolState.WalkLeft: enemy.Movement = new Vector2((-(float)walkSpeed), enemy.Movement.Y); break; case PatrolState.WalkRight: enemy.Movement = new Vector2(((float)walkSpeed), enemy.Movement.Y); break; } break; case EnemyState.Damaged: enemy.Movement = new Vector2(0f, enemy.Movement.Y); break; case EnemyState.Aggro: if ((!facingRight && Math.Abs(Game1.player.X - enemy.X) < 150) || (facingRight && Math.Abs(Game1.player.X - enemy.X) < 100)) { enemy.State = EnemyState.Attack; frameCounter = 0; } else if (Game1.player.X > enemy.X) { FacingRight = true; enemy.Right = true; patrolState = PatrolState.WalkRight; if (AbleToMove()) { enemy.Movement = new Vector2(((float)walkSpeed), enemy.Movement.Y); } } else { FacingRight = false; enemy.Right = false; patrolState = PatrolState.WalkLeft; if (AbleToMove()) { enemy.Movement = new Vector2((-(float)walkSpeed), enemy.Movement.Y); } } break; case EnemyState.Attack: frameCounter++; if (frameCounter == 30) { enemy.State = EnemyState.Aggro; } if (Game1.player.X > enemy.X) { FacingRight = true; patrolState = PatrolState.WalkRight; } else { FacingRight = false; patrolState = PatrolState.WalkLeft; } if (frameCounter == 25) { if (facingRight) { Rectangle temp = new Rectangle((int)enemy.X + 64, (int)enemy.Y, 32, 64); if (temp.Intersects(new Rectangle((int)Game1.player.position.X, (int)Game1.player.position.Y, (int)Game1.player.Size.X, (int)Game1.player.Size.Y))) { Game1.player.TakeDamage(1); } } else { Rectangle temp = new Rectangle((int)enemy.X - 64, (int)enemy.Y, 32, 64); if (temp.Intersects(new Rectangle((int)Game1.player.position.X, (int)Game1.player.position.Y, (int)Game1.player.Size.X, (int)Game1.player.Size.Y))) { Game1.player.TakeDamage(1); } } } break; case EnemyState.Search: break; // TODO: Add Search, Aggro, and Attack movements default: throw new NotImplementedException($"AI movement not implemented for {Enum.GetName(typeof(EnemyState), enemy.State)} state in AI.MoveAI()"); } }