Skip to content

Instantly share code, notes, and snippets.

@ryosuzuki
Last active March 25, 2019 00:26
Show Gist options
  • Save ryosuzuki/9f574debdb71577073ac4ba047fe7fde to your computer and use it in GitHub Desktop.
Save ryosuzuki/9f574debdb71577073ac4ba047fe7fde to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using RVO;
using UnityEngine;
using Random = System.Random;
using Vector2 = RVO.Vector2;
public class GameAgent : MonoBehaviour
{
[HideInInspector] public int sid = -1;
/** Random number generator. */
private Random m_random = new Random();
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (sid >= 0)
{
Vector2 pos = Simulator.Instance.getAgentPosition(sid);
Vector2 vel = Simulator.Instance.getAgentPrefVelocity(sid);
transform.position = new Vector3(pos.x(), transform.position.y, pos.y());
if (Math.Abs(vel.x()) > 0.01f && Math.Abs(vel.y()) > 0.01f)
transform.forward = new Vector3(vel.x(), 0, vel.y()).normalized;
}
if (!Input.GetMouseButton(1))
{
Simulator.Instance.setAgentPrefVelocity(sid, new Vector2(0, 0));
return;
}
Vector2 goalVector = GameMainManager.Instance.mousePosition - Simulator.Instance.getAgentPosition(sid);
if (RVOMath.absSq(goalVector) > 1.0f)
{
goalVector = RVOMath.normalize(goalVector);
}
Simulator.Instance.setAgentPrefVelocity(sid, goalVector);
/* Perturb a little to avoid deadlocks due to perfect symmetry. */
float angle = (float) m_random.NextDouble()*2.0f*(float) Math.PI;
float dist = (float) m_random.NextDouble()*0.0001f;
Simulator.Instance.setAgentPrefVelocity(sid, Simulator.Instance.getAgentPrefVelocity(sid) +
dist*
new Vector2((float) Math.Cos(angle), (float) Math.Sin(angle)));
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using Lean;
using RVO;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Assertions.Comparers;
using UnityEngine.Experimental.UIElements;
using Random = System.Random;
using Vector2 = RVO.Vector2;
public class GameMainManager : SingletonBehaviour<GameMainManager>
{
public GameObject agentPrefab;
[HideInInspector] public Vector2 mousePosition;
private Plane m_hPlane = new Plane(Vector3.up, Vector3.zero);
private Dictionary<int, GameAgent> m_agentMap = new Dictionary<int, GameAgent>();
// Use this for initialization
void Start()
{
Simulator.Instance.setTimeStep(0.25f);
Simulator.Instance.setAgentDefaults(15.0f, 10, 5.0f, 5.0f, 2.0f, 2.0f, new Vector2(0.0f, 0.0f));
// add in awake
Simulator.Instance.processObstacles();
}
private void UpdateMousePosition()
{
Vector3 position = Vector3.zero;
Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
float rayDistance;
if (m_hPlane.Raycast(mouseRay, out rayDistance))
position = mouseRay.GetPoint(rayDistance);
mousePosition.x_ = position.x;
mousePosition.y_ = position.z;
}
void DeleteAgent()
{
float rangeSq = float.MaxValue;
int agentNo = Simulator.Instance.queryNearAgent(mousePosition, 1.5f);
if (agentNo == -1 || !m_agentMap.ContainsKey(agentNo))
return;
Simulator.Instance.delAgent(agentNo);
LeanPool.Despawn(m_agentMap[agentNo].gameObject);
m_agentMap.Remove(agentNo);
}
void CreatAgent()
{
int sid = Simulator.Instance.addAgent(mousePosition);
if (sid >= 0)
{
GameObject go = LeanPool.Spawn(agentPrefab, new Vector3(mousePosition.x(), 0, mousePosition.y()), Quaternion.identity);
GameAgent ga = go.GetComponent<GameAgent>();
Assert.IsNotNull(ga);
ga.sid = sid;
m_agentMap.Add(sid, ga);
}
}
// Update is called once per frame
private void Update()
{
UpdateMousePosition();
if (Input.GetMouseButtonUp(0))
{
if (Input.GetKey(KeyCode.Delete))
{
DeleteAgent();
}
else
{
CreatAgent();
}
}
Simulator.Instance.doStep();
}
}
using System.Collections;
using System.Collections.Generic;
using RVO;
using UnityEngine;
using Vector2 = RVO.Vector2;
public class ObstacleCollect : MonoBehaviour
{
void Awake()
{
BoxCollider[] boxColliders = GetComponentsInChildren<BoxCollider>();
for (int i = 0; i < boxColliders.Length; i++)
{
float minX = boxColliders[i].transform.position.x -
boxColliders[i].size.x*boxColliders[i].transform.lossyScale.x*0.5f;
float minZ = boxColliders[i].transform.position.z -
boxColliders[i].size.z*boxColliders[i].transform.lossyScale.z*0.5f;
float maxX = boxColliders[i].transform.position.x +
boxColliders[i].size.x*boxColliders[i].transform.lossyScale.x*0.5f;
float maxZ = boxColliders[i].transform.position.z +
boxColliders[i].size.z*boxColliders[i].transform.lossyScale.z*0.5f;
IList<Vector2> obstacle = new List<Vector2>();
obstacle.Add(new Vector2(maxX, maxZ));
obstacle.Add(new Vector2(minX, maxZ));
obstacle.Add(new Vector2(minX, minZ));
obstacle.Add(new Vector2(maxX, minZ));
Simulator.Instance.addObstacle(obstacle);
}
}
// Update is called once per frame
void Update()
{
}
}
using UnityEngine;
using System.Collections;
using System;
public abstract class Singleton<T>
{
private static T _instance;
private static readonly object _lock = new object();
public static T Instance
{
get
{
lock (_lock)
{
if (_instance != null)
return _instance;
_instance = (T) Activator.CreateInstance(typeof(T), true);
(_instance as Singleton<T>).InitInstance();
return _instance;
}
}
}
public virtual void InitInstance()
{
}
}
/// <summary>
/// use InitInstance init not awake or start
/// support multi scene, you can added SingletonBehaviour in each scene for support run single scene (use same manager.prefab)
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class SingletonBehaviour<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
private static object _lock = new object();
public static T Instance
{
get
{
if (_applicationIsQuitting)
{
Debug.Log("[Singleton] Instance '" + typeof(T) +
"' already destroyed on application quit." +
" Won't create again - returning null.");
return null;
}
lock (_lock)
{
if (_instance != null)
return _instance;
_instance = (T) FindObjectOfType(typeof(T));
if (FindObjectsOfType(typeof(T)).Length > 1)
{
Debug.LogError("[Singleton] Something went really wrong " +
" - there should never be more than 1 singleton!" +
" Reopening the scene might fix it.");
return _instance;
}
if (_instance != null)
return _instance;
var singleton = new GameObject();
_instance = singleton.AddComponent<T>();
singleton.name = "(singleton) " + typeof(T).ToString();
Debug.Log("[Singleton] An instance of " + typeof(T) +
" is needed in the scene, so '" + singleton +
"' was created with DontDestroyOnLoad.");
return _instance;
}
}
}
private static bool _applicationIsQuitting = false;
private void Awake()
{
if (Instance == this)
{
DontDestroyOnLoad(transform.gameObject);
InitInstance();
}
else
Destroy(this.gameObject);
}
/// <summary>
/// When Unity quits, it destroys objects in a random order.
/// In principle, a Singleton is only destroyed when application quits.
/// If any script calls Instance after it have been destroyed,
/// it will create a buggy ghost object that will stay on the Editor scene
/// even after stopping playing the Application. Really bad!
/// So, this was made to be sure we're not creating that buggy ghost object.
/// </summary>
public virtual void OnDestroy()
{
if (_instance == this)
_applicationIsQuitting = true;
}
public virtual void InitInstance()
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment