Skip to content

Instantly share code, notes, and snippets.

@digital-synapse
Created December 9, 2017 03:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digital-synapse/12bc70e494067b85564a2039d184b65c to your computer and use it in GitHub Desktop.
Save digital-synapse/12bc70e494067b85564a2039d184b65c to your computer and use it in GitHub Desktop.
Unity base component for fast communication
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
/// <summary>
/// Base Component Class - Allows declaration of any component with a listener interface
/// </summary>
/// <typeparam name="TListenerInterface"></typeparam>
public class ComponentBase<TListenerInterface> : MonoBehaviour
{
public ComponentBase(Scope broadcastLevel = Scope.Self, bool cacheListeners = true, bool lazyLoad = true)
{
this.cacheListeners = cacheListeners;
if (cacheListeners && !lazyLoad) {
var load = listeners;
}
switch (broadcastLevel)
{
case Scope.Self:
getComponentInScope = GetComponents<TListenerInterface>;
break;
case Scope.SelfAndProgeny:
getComponentInScope = GetComponentsInChildren<TListenerInterface>;
break;
case Scope.Children:
getComponentInScope = GetComponentsInDirectChildren<TListenerInterface>;
break;
case Scope.SelfAndChildren:
getComponentInScope = GetComponentsInSelfAndDirectChildren<TListenerInterface>;
break;
case Scope.SelfAndAncestors:
getComponentInScope = GetComponentsInParent<TListenerInterface>;
break;
case Scope.Parent:
getComponentInScope = GetComponentsInDirectParent<TListenerInterface>;
break;
case Scope.SelfAndParent:
getComponentInScope = GetComponentsInSelfAndDirectParent<TListenerInterface>;
break;
case Scope.SelfProgenyAndAncestors:
getComponentInScope = GetComponentsInSelfProgenyAndAncestors<TListenerInterface>;
break;
case Scope.Scene:
getComponentInScope = GetComponentsInScene<TListenerInterface>;
break;
default: throw new ArgumentException("Unknown scope: components can not be resolved");
}
}
private bool cacheListeners;
private TListenerInterface[] _listenerCache;
protected TListenerInterface[] listeners
{
get
{
if (cacheListeners)
return _listenerCache == null
? _listenerCache = getComponentInScope()
: _listenerCache;
else
return getComponentInScope();
}
}
private Func<TListenerInterface[]> getComponentInScope;
public T[] GetComponentsInDirectChildren<T>()
{
return transform.Cast<Transform>().SelectMany(t => t.GetComponents<T>()).ToArray();
}
public T[] GetComponentsInSelfAndDirectChildren<T>()
{
return transform.Cast<Transform>().SelectMany(t => t.GetComponents<T>()).Concat(GetComponents<T>()).ToArray();
}
public T[] GetComponentsInDirectParent<T>()
{
return transform.parent.GetComponents<T>();
}
public T[] GetComponentsInSelfAndDirectParent<T>()
{
return transform.parent.GetComponents<T>().Concat(GetComponents<T>()).ToArray();
}
public T[] GetComponentsInScene<T>()
{
var roots = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects();
return roots.SelectMany(x => x.GetComponentsInChildren<T>()).ToArray();
}
public T[] GetComponentsInSelfProgenyAndAncestors<T>()
{
return GetComponentsInChildren<T>().Union(GetComponentsInParent<T>()).ToArray();
}
}
public enum Scope
{
Self,
Children,
SelfAndChildren,
SelfAndProgeny,
Parent,
SelfAndParent,
SelfAndAncestors,
SelfProgenyAndAncestors,
Scene
}
using UnityEngine;
// any other components can implement this interface to listen for mouse drag messages
public interface IMouseDragListener
{
void eventDragStart(Line line);
void eventDragStop(Line line);
}
public class MouseDrag : ComponentBase<IMouseDragListener>
{
// dragging
bool lmouseState = false;
Vector3 mouseDownPos;
Vector3 mouseUpPos;
bool dragging = false;
bool dragStart = false;
bool rmouseDown = false;
bool lmousedown = false;
private void Update()
{
// drag state machine logic
lmousedown = Input.GetMouseButtonDown(0);
if (lmousedown) mouseDownPos = Input.mousePosition;
var lms = Input.GetMouseButton(0);
if (lms && !lmouseState)
dragStart = true;
else if (!lms && lmouseState)
{
if (dragging) broadcastDragStop();
dragStart = false;
dragging = false;
}
if (dragStart && (Input.mousePosition - mouseDownPos).magnitude > 1)
{
if (!dragging) broadcastDragStart();
dragging = true;
}
lmouseState = lms;
}
private void broadcastDragStart()
{
foreach (var listener in listeners)
listener.eventDragStart(new Line() { start = mouseDownPos });
//SendMessage("eventDragStart", new Line() { start = mouseDownPos }, SendMessageOptions.RequireReceiver);
}
private void broadcastDragStop()
{
foreach (var listener in listeners)
listener.eventDragStop(new Line() { start = mouseDownPos, end = mouseUpPos });
//SendMessage("eventDragStop", new Line() { start = mouseDownPos, end = mouseUpPos }, SendMessageOptions.RequireReceiver);
}
}
public struct Line
{
public Vector2 start, end;
public Vector2 vectorLine { get { return end - start; } }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment