Skip to content

Instantly share code, notes, and snippets.

@SteveSwink
Created February 19, 2013 22:57
Show Gist options
  • Save SteveSwink/4991015 to your computer and use it in GitHub Desktop.
Save SteveSwink/4991015 to your computer and use it in GitHub Desktop.
star map
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class StarMap : MonoBehaviourSingleton<StarMap>{
public List<MapPoint> mapPoints = new List<MapPoint>();
public MapPoint currentLocation;
public float maxDestinationDistance = 130f;
public Material selectedPathMaterial;
public Material unselectedPathMaterial;
public Material emptyPathMaterial;
public Material reticleOffMaterial;
public Material reticleCurrentMaterial;
public Material reticleSelectedMaterial;
public Transform ship;
public Transform shipPrefab;
public float shipSpeed = 1.1f; // TODO calculate the ship speed based on your engines
public Transform currentLocationLabelPrefab;
public Vector3 currentLabelOffset = new Vector3(0,-1,0);
public GameObject noSelectionMessage;
[HideInInspector]
public Transform currentLocationLabel;
[HideInInspector]
public MapPoint selectedLocation;
[HideInInspector]
public MapPoint mouseOverLocation;
StateMachine sm = new StateMachine();
Vector3 reticleStartSize;
bool shipMoving = false;
void Start () {
// Grab the stars in the scene and dump to list
MapPoint[] tempStars = FindObjectsOfType(typeof(MapPoint)) as MapPoint[];
foreach(MapPoint s in tempStars){
mapPoints.Add(s);
}
// our starting location. Pick random if none set
if(currentLocation == null){
currentLocation = mapPoints[Random.Range(0,mapPoints.Count-1)];
}
// create the ship
if(ship == null)
ship = (Transform)Instantiate(shipPrefab, transform.position, transform.rotation);
// create the current location label and activate
currentLocationLabel = (Transform)Instantiate(currentLocationLabelPrefab, transform.position, transform.rotation);
currentLocationLabel.gameObject.SetActive(true);
currentLocationLabel.parent = ship;
// whatever location we found, set to current ship location
SetCurrentLocation(currentLocation);
// default the location contents
currentLocation.contents = MapPoint.Type.Debris;
currentLocation.SetLabel("Debris");
// yeild one frame to make sure all the MapPoints are set up first
StartCoroutine(RandomizeMapPoints());
// subscribe to the engage button message
EventRouter.Subscribe("Engage", EngageButtonPressed);
sm.ChangeState(enterOFF, updateOFF, exitOFF);
}
IEnumerator RandomizeMapPoints(){
yield return new WaitForEndOfFrame();
foreach(MapPoint m in mapPoints){
// randomize the type of location this is
int enumlen = System.Enum.GetNames(typeof(MapPoint.Type)).Length;
int rand = Random.Range(0,enumlen);
m.contents = (MapPoint.Type)rand;
}
SetMapPointLabels();
EnableMapPointsInRange();
}
// MOUSEOVER State
bool enterOVER ()
{
// Activate reticle and label - function on MapPoint?
mouseOverLocation.reticle.gameObject.renderer.enabled = true;
return true;
}
bool updateOVER ()
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 1000)){
if(hit.collider.gameObject != mouseOverLocation.gameObject){
sm.ChangeState(enterOFF, updateOFF, exitOFF);
return false;
}
MapPoint mp = hit.collider.gameObject.GetComponent<MapPoint>() as MapPoint;
if(mp){
if(Input.GetMouseButtonDown(0)){
if(selectedLocation!=null){
selectedLocation.lineRenderer.material = unselectedPathMaterial;
selectedLocation.reticle.gameObject.renderer.enabled =false;
selectedLocation.reticle.localScale = reticleStartSize;
}
// set the location we found as the selected location
selectedLocation = mp;
// if the star is out of range, do nothing
int temp = GetStarDistance(selectedLocation, currentLocation);
if( temp > maxDestinationDistance){
return false;
}
// turn on the blue reticle to show that this is currently selected
selectedLocation.reticle.renderer.material = reticleSelectedMaterial;
// change this line renderer
selectedLocation.lineRenderer.material = selectedPathMaterial;
// store reticle size so we can restore it when we change selected
reticleStartSize = selectedLocation.reticle.localScale;
//pulse tween on selected reticle
iTween.StopByName("pulse");
Vector3 scaleTo = reticleStartSize * 0.9f;
iTween.ScaleTo(selectedLocation.reticle.gameObject,
iTween.Hash(
"time", 0.5f,
"name", "pulse",
"scale", scaleTo,
"easetype", iTween.EaseType.easeInOutSine,
"looptype", iTween.LoopType.pingPong)
);
}
}
}else{
sm.ChangeState(enterOFF, updateOFF, exitOFF);
}
return false;
}
bool exitOVER ()
{
return true;
}
// MOUSEOFF State
bool enterOFF ()
{
if(mouseOverLocation == selectedLocation){
return true;
}
if(mouseOverLocation != null){
// reticle on but set to faded
mouseOverLocation.reticle.renderer.enabled = false;
mouseOverLocation.reticle.renderer.material = reticleOffMaterial;
// mouse over to null, waits to be set by updateOFF
mouseOverLocation = null;
}
return true;
}
bool updateOFF ()
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 1000)){
MapPoint mp = hit.collider.gameObject.GetComponent<MapPoint>() as MapPoint;
// if we mouse over the current or selected location, ignore
if(mp == currentLocation) return false;
if(mp == selectedLocation) return false;
// if the star is too far, ignore
if(GetStarDistance(currentLocation, mp) > maxDestinationDistance) return false;
if(mp){
mouseOverLocation = mp;
sm.ChangeState(enterOVER, updateOVER, exitOVER);
}
}
return false;
}
bool exitOFF ()
{
return true;
}
// SHIPMOVING
bool enterSHIPMOVING ()
{
return true;
}
bool updateSHIPMOVING ()
{
return false;
}
bool exitSHIPMOVING ()
{
return true;
}
// Update is called once per frame
void Update () {
sm.Execute();
}
void SetCurrentLocation(MapPoint mp){
currentLocation = mp;
currentLocationLabel.position = currentLocation.transform.position + currentLabelOffset;
ship.position = currentLocation.transform.position;
}
void EngageButtonPressed(EventRouter.Event evt){
// if we have no selected location display message
if(selectedLocation == null){
StartCoroutine(DisplayNoSelectionMessage());return;
}
if(shipMoving) return;
// if we have a selected location, move there
MoveToNewLocation(selectedLocation);
}
void OnDestroy(){
// Unsubscribe us from this event
EventRouter.Unsubscribe("Engage", EngageButtonPressed);
}
IEnumerator DisplayNoSelectionMessage(){
// cheapy flash effect on message
noSelectionMessage.SetActive(true);
yield return new WaitForSeconds(0.25f);
noSelectionMessage.SetActive(false);
yield return new WaitForSeconds(0.25f);
noSelectionMessage.SetActive(true);
yield return new WaitForSeconds(0.25f);
noSelectionMessage.SetActive(false);
yield return new WaitForSeconds(0.25f);
noSelectionMessage.SetActive(true);
yield return new WaitForSeconds(0.25f);
noSelectionMessage.SetActive(false);
}
void DisableAllMapPointLineRenderers(){
foreach(MapPoint m in mapPoints){
m.lineRenderer.material = emptyPathMaterial;
}
}
void DisableAllMapPointLabels(){
foreach(MapPoint m in mapPoints){
m.label.renderer.enabled = false;
}
}
void EnableAllMapPointLabels(){
foreach(MapPoint m in mapPoints){
m.label.renderer.enabled = true;
}
}
void EnableMapPointsInRange(){
foreach(MapPoint m in mapPoints){
if(m == selectedLocation) return;
float dist = Vector3.Distance(currentLocation.transform.position, m.transform.position);
dist*=10000*dist;
if(dist < maxDestinationDistance){
m.lineRenderer.material = unselectedPathMaterial;
}else{
m.lineRenderer.material = emptyPathMaterial;
}
}
}
public int GetStarDistance(MapPoint obj1, MapPoint obj2){
float dist = Vector3.Distance(obj1.transform.position, obj2.transform.position);
dist *=10000*dist;
int distTemp = (int)dist;
return distTemp;
}
void SetMapPointLabels(){
foreach(MapPoint m in mapPoints){
float dist = Vector3.Distance(m.transform.position, currentLocation.transform.position);
dist *=10000*dist;
int distTemp = (int)dist;
string distString = string.Format("{0:#,###0}", distTemp);
distString = "\n" + distString;
distString += " km";
m.SetLabel( m.contents.ToString() + distString);
if(dist > maxDestinationDistance){
m.label.renderer.enabled = false;
}else{m.label.renderer.enabled =true;}
}
}
void MoveToNewLocation(MapPoint newLocation){
DisableAllMapPointLineRenderers();
DisableAllMapPointLabels();
selectedLocation.reticle.renderer.enabled = false;
shipMoving = true;
// switch to the dummy SHIPMOVING state
sm.ChangeState(enterSHIPMOVING, updateSHIPMOVING, exitSHIPMOVING);
// Move the ship with an itween
iTween.MoveTo(ship.gameObject, iTween.Hash("position", newLocation.transform,
"easetype", iTween.EaseType.easeInOutSine,
"speed", shipSpeed,
"onupdatetarget", gameObject,
"oncompletetarget", gameObject,
"onupdate", "ShipMovingUpdate",
"oncomplete","ShipReachedDestination"));
// Tick down global values according to travel rates
PlayerGlobals.Instance.BurnFuel(0.1f);
// If we make it to our destination, update currentLocation
EventRouter.Publish("UpdateStarmapLoctation", this, currentLocation);
}
void ShipMovingUpdate(){
}
void ShipReachedDestination(){
shipMoving = false;
PlayerGlobals.Instance.StopBurningFuel();
selectedLocation.lineRenderer.material = unselectedPathMaterial;
// set this location as our current location
SetCurrentLocation(selectedLocation);
// let the map points know they have a new current
EventRouter.Publish("UpdateStarmapLocation", gameObject, currentLocation.transform);
selectedLocation = null;
EnableMapPointsInRange();
SetMapPointLabels();
// EnableAllMapPointLabels();
// re-enable the reticles
sm.ChangeState(enterOFF, updateOFF, exitOFF);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment