Skip to content

Instantly share code, notes, and snippets.

@PappaBjorn
Last active February 4, 2020 13:06
Show Gist options
  • Save PappaBjorn/77b84a97ee874ddc93771a98c434aeea to your computer and use it in GitHub Desktop.
Save PappaBjorn/77b84a97ee874ddc93771a98c434aeea to your computer and use it in GitHub Desktop.
Dev tools and components for Owlchemist
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
public class AIPerception : MonoBehaviour
{
public float perceptionRadius = 1f;
[Range(0, 360f)] public float fovAngle = 100f;
public LayerMask perceptionMask;
public Material seenMaterial;
public Material unseenMaterial;
public List<Collider> previouslySeen = new List<Collider>();
public ChickenStateMachine chickenStateMachine;
private void Awake()
{
chickenStateMachine = GetComponent<ChickenStateMachine>();
Assert.IsNotNull(chickenStateMachine, "<b>AIPerception</b> failed to locate <b>ChickenStateMachine</b> on Enemy GameObject");
}
private void Update()
{
for (int i = 0; i < previouslySeen.Count; i++)
{
// material renderer for sphere above player. Debug reasons only!
previouslySeen[i].GetComponent<Renderer>().sharedMaterial = unseenMaterial;
chickenStateMachine.seeingPlayer = false;
}
previouslySeen.Clear();
previouslySeen.AddRange(Physics.OverlapSphere(transform.position, perceptionRadius, perceptionMask, QueryTriggerInteraction.Ignore));
for (int i = 0; i < previouslySeen.Count; i++)
{
Vector3 direction = previouslySeen[i].transform.position - transform.position;
float angle = Vector3.Angle(direction, transform.forward);
if (angle <= fovAngle * 0.5f)
{
// material renderer for sphere above player. Debug reasons only!
previouslySeen[i].GetComponent<Renderer>().sharedMaterial = seenMaterial;
chickenStateMachine.seeingPlayer = true;
}
}
}
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
if (!Application.isPlaying)
{
Color oldColor = Gizmos.color;
float halfFOV = fovAngle * 0.5f;
float coneDir = -90f;
Quaternion leftRayRotation = Quaternion.AngleAxis(-halfFOV + coneDir, Vector3.up);
Quaternion rightRayRotation = Quaternion.AngleAxis(halfFOV + coneDir, Vector3.up);
Vector3 leftDir = leftRayRotation * transform.right * perceptionRadius;
Vector3 rightDir = rightRayRotation * transform.right * perceptionRadius;
UnityEditor.Handles.color = new Color(0f, 1f, 0f, 0.15f);
UnityEditor.Handles.DrawSolidArc(transform.position, Vector3.up, leftDir, fovAngle, perceptionRadius);
UnityEditor.Handles.color = new Color(1f, 0f, 0f, 0.15f);
UnityEditor.Handles.DrawSolidArc(transform.position, Vector3.up, rightDir, 360f - fovAngle, perceptionRadius);
Gizmos.color = oldColor;
}
}
#endif
}
using UnityEngine;
public class AIWaypointSystem : MonoBehaviour
{
public Vector3[] wayPoints;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class NavMeshComponent : BaseComponent
{
public GameObject surfaceObject;
public float distanceThreshold = 3f;
[HideInInspector]
public NavMeshSurface surface;
public delegate void UpdateNavMeshDelegate();
public UpdateNavMeshDelegate OnUpdateNavMesh;
public void Awake()
{
surface = surfaceObject.GetComponent<NavMeshSurface>();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NavMeshSystem : BaseSystem
{
private Filter[] filters;
[System.Serializable]
public struct Filter
{
public Filter(
int id,
GameObject go,
NavMeshComponent navComp
)
{
this.id = id;
gameObject = go;
navMeshComponent = navComp;
}
public int id;
public GameObject gameObject;
public NavMeshComponent navMeshComponent;
}
public override void Initialize(Transform[] objects)
{
List<Filter> tmpFilters = new List<Filter>();
int index = 0;
for (int i = 0; i < objects.Length; i++)
{
NavMeshComponent navMeshComponent = objects[i].GetComponent<NavMeshComponent>();
if (navMeshComponent)
{
tmpFilters.Add(new Filter(index, objects[i].gameObject, navMeshComponent));
navMeshComponent.surface.BuildNavMesh();
navMeshComponent.OnUpdateNavMesh += UpdatePlayerNavMesh;
}
}
filters = tmpFilters.ToArray();
}
public override void SetupInputComponent(InputComponent inputComponent)
{
player.eventComponent.OnGatherResource += UpdatePlayerNavMesh;
}
public override void Tick(float deltaTime)
{
for (int i = 0; i < filters.Length; i++)
{
// cache variables
Filter filter = filters[i];
NavMeshComponent navMeshComponent = filter.navMeshComponent;
if (Vector3.Distance(navMeshComponent.transform.position, navMeshComponent.surface.transform.position) >= navMeshComponent.distanceThreshold)
{
UpdateNavMesh(navMeshComponent);
}
}
}
private void UpdateNavMesh(NavMeshComponent navMeshComponent)
{
navMeshComponent.surface.RemoveData();
navMeshComponent.surface.transform.position = navMeshComponent.transform.position;
navMeshComponent.surface.BuildNavMesh();
}
private void UpdatePlayerNavMesh()
{
Debug.Log("Updating navmesh");
player.navMeshComponent.surface.RemoveData();
player.navMeshComponent.surface.transform.position = player.navMeshComponent.transform.position;
player.navMeshComponent.surface.BuildNavMesh();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class NavMeshUpdater : MonoBehaviour
{
public NavMeshSurface surface;
public float distanceThreshold = 5f;
void Awake()
{
surface.BuildNavMesh();
//surface.BuildNavMesh();
UpdateNavMesh();
}
// Update is called once per frame
void Update()
{
if (Vector3.Distance(transform.position, surface.transform.position) >= distanceThreshold)
UpdateNavMesh();
}
void UpdateNavMesh()
{
surface.RemoveData();
surface.transform.position = transform.position;
surface.BuildNavMesh();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment