Posts

Showing posts from 2019

A* Pathfinding: Debugging Special Cases

December 19, 2019 A* Pathfinding Debugging Special Cases ISSUES Getting an Index Out of Bounds Error in EnemyBasicMovement Script Error happening on this line: Vector3 direction = (path.lookPoints[0] - transform.position).normalized; Suggests that the very first point in a path does not exist, so somehow empty paths are being passed through the system. Test 1: Increase A* Grid Size to Cover Entire Play Area and Spawn Points Some of the spawn points are a bit off of the normal play area, so I made sure to cover anywhere the units could possibly exist with the A* grid so they always had a node to latch onto (even though I believe the clamping should cover this error). This did not end up being the issue as the error persisted. Test 2: Increase Size of Walkable Plane Over Entire Play Area Similar to the logic of Test 1, I just wanted to make sure the nodes were not not being created because the units were missing some usual piece of information they would have to m

A* Pathfinding: Edit for 2D

December 19, 2019 A* Pathfinding 2D Conversion ISSUES Pathing In Circles Away from Target They move in a large circle around the entire game area. They go in a half circle consistenly then stop in about the same place everytime (either directly above or below the middle of the play area). Test 1: Tone Values Down I tried toning all their numbers down since my game area is relatively small in case they were just constantly over shooting node targets, but this did not change the behavior. I think the direction I am aiming and moving them must be incorrect with how I changed the Vector math from 3D to 2D. DETERMINED ISSUE They can only respond to the player's X position. If the player moves, the properly oriented ones will move slightly to keep at the same X value, whereas those facing the other direction will travel in a large circle to reach the same X value (since I guess they cannot rotate very easily). Test 2: Edit Rotation Calculation I just needed to remo

How Command & Conquer: Tiberian Sun Solved Pathfinding: War Stories: Ars Technica

December 18, 2019 War Stories How Command & Conquer: Tiberian Sun Solved Pathfinding How Command & Conquer: Tiberian Sun Solved Pathfinding | War Stories | Ars Technica Link - Video By: Ars Technica Working on Pathfinding Pathfinding, especially in a dynamic sense, is still a relatively expensive process to run. This is much more so when you are trying to apply it to a lot of units. Tiberian Sun was running into a lot of issues they called "Artificial Idiocy", which is when your AI just does really dumb stuff. Really illogical AI from a player's game units very quickly make the player mad and aggitated. They say "If you spend more time making sure it doesn't do something stupid, it will actually look pretty smart". And to follow up, they didn't need perfect pathfinding, they just needed "not stupid" pathfinding. Some of their fixes included not accounting for the collision of other friendly units selected to move and w

Unity Event Systems: Introductory Research

December 17, 2019 Unity Event Systems Basics, Setup, and Tutorials ADDENDUM: An EVEN MORE AWESOME Event System, by viewers! Link - Tutorial 1 By: quill18creates C# Events Link - Tutorial 2 By: Jonathan Weinberger {ON Unity Learn Premium} Tutorial 1 They created a public abstract class, Event , that all types of events will just inherit from. This helps keep all your events nice and similar, as well as making sure they all have key methods such as those necessary for registering and unregistering listeners. Since each event type is its own version of this base event, they can each hold a different collection of listeners, which makes sense since you only want certain behaviors to happen when certain events happen (such as a unit dying). Inheritance and Static Fields in C# This was an interesting interaction that I did not know it worked this way. When a base class in C# contains a static field, and then you create a new class that inherits from this class, it

Sebastian Lague A* Tutorial Series - Threading - Pt. 10

December 16, 2019 A* Tutorial Series A* Pathfinding (E10: threading) A* Pathfinding (E10: threading) Link - Tutorial By: Sebastian Lague Intro: This tutorial gets into the idea of threading to help relieve some of the burden on processing caused by the pathfinding logic. Threading is not something I understand very well, so I will have to look into this more in the future, but I wanted to cover this tutorial just for completions sake. Tutorial This setup usese another namespace, the System.Threading namespace. This lets them use the ThreadStart delegate type and the lock keyword. ThreadStart can be assigned the value of some other delegate, with in this case contained the FindPath method from PathfindingHeap. I then looked up the lock keyword here: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement While this sort of threading setup has some unique syntax, it is an otherwise simple setup. There is a queue of PathResults

HFFWS Generate Scenario As Gameobject Hierarchy

Image
December 15, 2019 HFFWS Generation System Scenario Gameobject Hierarchy Connecting the System for Scenario Gameobject Hierarchy Organization To help with organization of the overall system in Unity, I wanted each generated scenario to be fully contained within its own, single gameobject hierarchy. To do this, I had the DemoManager, my highest level in the system, create an overall gameobject that will act as the parent for the entire scenario hieararchy. This reference was then passed to the current ScenarioManager object, which can then pass it to all of its associated Create classes so they can all instantiate their chosen objects as children of that same parent gameobject. The other benefit of this is that it helps with spacing out the individual scenarios for my DemoManager. The instantiated empty parent gameobjects have their transform.position set by the spacingBetweenScenarios variable within the DemoManager. This gives everything childed to it some significa

Coroutine Error Investigation in A* Tutorial Series - Path Smoothing - E09

December 13, 2019 A* Tutorial Series A* Pathfinding (E09: path smoothing 2/2) A* Pathfinding (E09: path smoothing 2/2) Link - Tutorial By: Sebastian Lague Intro I wanted to further my investigation on the issue I had with coroutines when dealing with updating the pathing of the A* units when following the A* tutorial series, specifically in episode 9. I have included the sections "Error with Updating Path" and "Fix for: Error with Updating Path" from my last post to keep them together, along with my updates for the investigation. Error with Updating Path For some reason my version was not working properly. The path was updating fine, as I could see with the visualization, but the unit would stop moving and never move toward the target again. I was getting an index out of bounds error, some I have some issue with one of my arrays somewhere, but not sure where. It was running fine in the tutorial, so I must have missed something. Fix for: Er

Sebastian Lague A* Tutorial Series - Path Smoothing - Pt. 08 and Pt. 09

December 13, 2019 A* Tutorial Series A* Pathfinding (E08: path smoothing 1/2) A* Pathfinding (E08: path smoothing 1/2) Link - Tutorial 1 By: Sebastian Lague A* Tutorial Series A* Pathfinding (E09: path smoothing 2/2) A* Pathfinding (E09: path smoothing 2/2) Link - Tutorial 2 By: Sebastian Lague A* Pathfinding (E08: path smoothing 1/2) Intro: These tutorials both covered the same general topic of smoothing the path of the unit. Theory Currently the units follow the path by making a straight line from one point to the next, which looks unnatural. To remedy this, they suggest a path smoothing technique. This system starts with each point having a small line pointing directly to the previous point, whose length is called the "turn distance". This line then has a perpendicular line emanating from the end, called the "turn boundary". Once the unit passes this turn boundary, it will start to turn towards the next point in the path (inste

HFFWS Scenario Building System

December 12, 2019 HFFWS Generation System Design Scenario and Create Class Interaction Detail on Scenario-Create Interaction My first pass on deciding on how to have the Scenario classes and Create classes interact uses the following flow: Scenario holds all parameter ranges Scenario picks random values within ranges Scenario holds these values in various fields (read only) Scenario calls overall creation method within each Create class Scenario passes parameters to Create class through this Create method The overall idea here is that the Scenario class can hold all the parameters necessary for all its Create classes, as well as the Inspector interface for setting the ranges for these parameters (so the designer can design the scenario from this single class object). As the Create classes determine their varied values within the sets of parameters, they can feed information back to the Scenario class to update how the other Create class parameter ranges are set. So

Sebastian Lague A* Tutorial Series - Smooth Weights - Pt. 07

December 10, 2019 A* Tutorial Series Pt. 07 - Smooth Weights A* Pathfinding (E07: smooth weights) Link - Tutorial By: Sebastian Lague Intro: This tutorial covers smoothing the movement penalty values out over an area, as opposed to the areas just directly being either one value or another. This will also be helpful for my uses as most cases when updating movement penalties in areas will not just want to update the single exact node where an important action happened. While that area should most likely have the largest impact on its weight, it will make sense to apply a light value change around that area as well. This seems to fit right in with smoothing or blending of weight values. Theory Box Blur: weight smoothing algorithm using averages of values within a kernel around a block in the grid Kernel: a smaller grid sample within the overall grid; used here as the space to gather data from to create an average value with The smoothing theory they look at i

Issues with Intellisense in Visual Studio in Unity

December 10, 2019 Unity and Visual Studio Intellisense Issues Good Solution Options for Unity / Visual Code Intellisence Issues Link - Possible Solutions For some reason Visual Studio 2019 does not want to use Intellisense properly on the HFFWS project when using Unity commands. It still autocompletes some general stuff that I assume is more generally C# focused, but methods like Start, Awake, OnCollisionEnter that are Unity specific do not complete. They still work and run fine, but the autocomplete feature is missing. I tried circumventing this by going back to Visual Studio 2017 as the code editor and it worked totally fine. This points to it being a VS 2019 issue directly, but it could also be how it interacts with Unity in general. I have to use an older version of Unity (2017.4.13f1) so maybe that has something to do with the issues that come up. People run into this issue all the time for various reasons, and I have tried a lot of their solutions to no av

Sebastian Lague A* Tutorial Series - Weights - Pt. 06

December 9, 2019 A* Tutorial Series Pt. 06 - Weights A* Pathfinding (E06: weights) Link - Tutorial By: Sebastian Lague Intro: Weights are exactly what I am looking for to influence the intelligence of the units in my project. They are an additional factor for moving in certain areas to make them more or less "appealing" to the AI to further influence their movement. This makes their movement more interesting than the simple "point A to point B" shortest distance. When importing the Road object, I had to scale mine up (x5) to fit my scene like the tutorial. Unsure if they changed the size of their scene at some point, so this may impact the way the units travel so it is important to keep in mind. This system is going to have the grid use a bunch of raycasts to see what they collide with to determine what type of terrain is in which area. The ray will return information on what terrain was hit, and this will relay the penalty information back

HFFWS Generation System Overview Update

Image
December 5, 2019 HFFWS Generation System Overview Update General System Overview I have updated my thoughts on setting up the overall system to fit the demands for my thesis as well as to keep everything more organized and readable. I am sure as I go through building this I will find ways to cut out levels of inheritance or add scripts for readability, but this is the most recent view on everything. I want the highest level to be very general (DemoManager), the middle level should be where the majority of parameter ranges and interactive placement between objects should be (ScenarioManager's), and the lowest level will be in charge of putting together the needed objects within the bounds dictated by the higher levels (Create classes). This image just shows the general idea of the overall hierarchy (the actual number of ScenarioManagers and Create classes is not accurate). The DemoManager holds references to all of the ScenarioManagers, but only chooses one Scena

Sebastian Lague A* Tutorial Series - Units - Pt. 05

December 4, 2019 A* Tutorial Series Pt. 05 - Units A* Pathfinding (E05: units) Link - Tutorial By: Sebastian Lague Intro: This tutorial focuses on passing the Pathfinding information to units so that they can actually use it to move. PathRequestManager and Updating Old Classes Having many units use this logic at once would be a bit too costly and could cause slow downs, so this needs to be managed and spread out in order to keep the game from slowing down or stopping. This was done by creating the PathRequestManager class. This was created to ensure only one request would be processed at a time. Requests were added to a queue, which are then popped off one at a time to fulfill. A simple bool check was used to ensure one request was being done at a time (isProcessingPath). A new struct named PathRequest was created within this class as well to make managing the data much easier. These PathRequest objects would hold a Vector3 for the start position, another

Sebastian Lague A* Tutorial Series - Heap Optimization - Pt. 04

December 2, 2019 A* Tutorial Series Pt. 04 - Heap Optimization A* Pathfinding (E04: heap optimization) Link - Tutorial By: Sebastian Lague Intro: This tutorial focused on converting the pathfinding setup over to a heap system to help speed up the process, especially for larger scaled environments and node grids. There is some useful theory at the beginning, and then it gets into heavier code work, so I again break down the classes later in the tutorial. General Heap Theory One of the first places to optimize this A* pathfinding is in the Pathfinding class where it searches through the entire open set every time it tries to determine the next lowest F cost node. Heap optimization will be used here to reduce the load of the process. A heap is basically a binary tree where each node branches out to two more nodes. The general rule of this tree is that the parent value is less than that of the children nodes. When placing a new node, it is placed at the end (on a

UnityLearn - Beginner Programming - Swords and Shovels: Character Controller and AI - Pt. 03 - Finalizing and Extending Systems

Novemeber 21, 2019 Beginner Programming: Unity Game Dev Courses Beginner Programming: Unity Game Dev Courses Unity Learn Course - Beginner Programming Finalizing and Extending Systems Designing with NavMesh Obstacles This section just showed how obstacles work with NavMesh. Objects with colliders can be given NavMeshObstacle components to work as obstacles within the NavMesh. The Carve bool lets you determine if they "carve out" parts of the NavMesh to make them inaccessible for agents with NavMesh driven AI. Finishing the Patrol System The InvokeRepeating method has a delay paramter as well. This can be given various values between different objects so they are not all on the exact same cycle. This was used to offset the waypoint traveling cycles of the goblin NPCs. Fine Tuning the Agents and Animation The logic that was making the player character awkwardly slow down around the stairs and other obstacles is found within the obstacle avoidance pa

UnityLearn - Beginner Programming - Swords and Shovels: Character Controller and AI - Pt. 02 - NPC Controller

Novemeber 21, 2019 Beginner Programming: Unity Game Dev Courses Beginner Programming: Unity Game Dev Courses Unity Learn Course - Beginner Programming NPC Controller Creating NPC Patrol The NPC has two main states: it will patrol within a set of waypoints or it will pursue the player. They create two main methods to control the NPC behavior, Patrol and Tick. Both of these are called in the Awake method of the NPCController through the use of the InvokeRepeating command. This is done because you can set a time value that needs to pass between each invocation, so basically they can perform these methods in a "slow Update" fashion. Tick is called every 0.5s, while Patrol is called every patrolTime, which was defaulted at 15s. The Patrol method used an inline ternary method to set the value of index, which is something I am not used to seeing. The line was as such: index = index == waypoints.Length - 1 ? 0 : index + 1; I believe this checks if index is

UnityLearn - Beginner Programming - Swords and Shovels: Character Controller and AI - Pt. 01 - Overview and Character Controller

Novemeber 21, 2019 Beginner Programming: Unity Game Dev Courses Beginner Programming: Unity Game Dev Courses Unity Learn Course - Beginner Programming Overview and Character Controller Navigation and Animation Review This part of the tutorial just gets you familiar with the NavMesh setup they have and the animator they are using on the player character. Some of the items are a bit off since they are using an older Unity version (2017), like where the Navigation tab is located (it is now under Window -> AI). The player character animator has a blend tree that holds a speed parameter. This parameter appears to determine how much to blend between an idle animation and a running animation, as well as how fast the animation plays. Controlling Motion with C# and Unity Events This tutorial portion started with adding a NavMesh Agent component to the Hero character to have it interact with the baked NavMesh in the scene. The next step was to edit the MouseManager

Sebastian Lague A* Tutorial Series - Algorithm Implementation - Pt. 03

November 20, 2019 A* Tutorial Series Pt. 03 - Algorithm Implementation A* Pathfinding (E03: algorithm implementation) Link - Tutorial By: Sebastian Lague Intro: Since these sections are very coding intensive, I just setup a breakdown into the different classes that are worked on. I try to discuss anything done within the class in that class's section here. As should be expected, they do not continuosly do a single section and move to the next, they jump back and forth so that the references and fields make more sense for why they exist, so I try to mention that if needed. Pathfinding This class begins to implement the psuedo code logic for the actual A* algorithm. It starts with a method, FindPath, that takes in two Vector3 values, one for the starting position and one for the target position. It then uses our NodeFromWorldPoint method in AGrid to determine which nodes those positions are associated with so we can do all the work with our node system. It

Sebastian Lague A* Tutorial Series - Node Grid - Pt. 02

November 20, 2019 A* Tutorial Series Pt. 02 - Node Grid A* Pathfinding (E02: node grid) Link - Tutorial By: Sebastian Lague Intro: This started by creating the overall Node class to contain valuable information for each individual node, and the Grid class that would be dealing with the overall grid of all the nodes (I rename this to AGrid to avoid errors in Unity). Node For now, this simply holds a bool walkable, which represents whether this node contains an obstacle or not, and a Vector3 worldPosition, which contains data on its Unity real world position. AGrid This class has a couple parameters that influence the coverage and resolution of the overall A* system. The gridWorldSize represents the two dimensions covered by the entire grid (so 30, 30 will cover a 30 by 30 area in Unity units). The nodeRadius is half the dimension of a node square, which will be used to fill the entire grid. The lower the nodeRadius, the more nodes (so higher resolution, but
Sebastian Lague A* Tutorial Series - Algorithm Explanation - Pt. 01 November 20, 2019 A* Tutorial Series Pt. 01 - Algorithm Explanation A* Pathfinding (E01: algorithm explanation) Link - Tutorial By: Sebastian Lague Notes: G cost = distance from starting node H cost (heuristic) = distance from the end node F cost = G cost + H cost A* starts by creating a grid of an area. There is a starting node (initial position) and an end node (destination). Generally, you can move orthogonally (which is normalized as a distance of 1) or diagonally (which would then be a value of sqrt of 2, which is approx. 1.4). Just to make it look nicer and easier to read, it is standard to multiply these distances by 10 so that moving orthogonally has a value of 10, and diagonally has a value of 14. The A* algorithm starts by generating the G cost and H cost of all 8 squares around the starting point (in a 2D example for ease of understanding). These are then used to calculate the F cost

Notes on Research Paper: Automatic Game Progression Design through Analysis of Solution Features by Butler et al.

November 19, 2019 Thesis Research Notes on Resources TITLE: Automatic Game Progression Design through Analysis of Solution Features AUTHORS: E. Butler, E. Andersen, A. M. Smith, S. Gulwani, and Z. Popović IEEE Citation - Zotero [1]E. Butler, E. Andersen, A. M. Smith, S. Gulwani, and Z. Popović, “Automatic Game Progression Design through Analysis of Solution Features,” 2015, pp. 2407–2416. ABSTRACT - use intelligent tutoring systems and progression strategies to help with mastery of base concepts  as well as combinations of these concepts - System input: model of what the player needs to do to complete each level - Expressed as either: - Imperative procedure for producing solutions - Representation of features common to all solutions - System output: progression of levels that can be adjusted by changing high level parameters INTRODUCTION - Level Progression: "how game introduces new concepts and grows in complexity as the player progres