I’m having problems getting my circle-oriented menu to rotate well (see below):
The icons move as commanded, but sometimes (depending on if there’s any lag on the PC), the icons do not move the entire angle because the coroutine ends before it can finish. Increasing the duration of the coroutine just makes the icons move slower and doesn’t guarantee that they go the full 51.XXXXX degrees that they have to go (there are 7 icons, so each one has to move 360/7 each time a left or right key is pressed). The final result is that the icons are lopsided and the selected icon is about 5 or 10 degrees to the right or left.
Also, when I move the circle of icons in one direction, then move it in another direction, the icons still move in the first direction and then switch to the new direction in a very jerky fashion.
How do I get the icons to move their complete angles without stopping, and how to I fix the jerky movement described above? I’m completely lost because I can’t figure out why its doing what it’s doing, so I can’t even begin to fix it.
Here is my complete code. It is self-contained:
using UnityEngine;
using System.Collections;
public class RingMenu : MonoBehaviour
{
int mScale = 1, selection;
float oX, oY, mX, mY, xCenter = (float)Screen.width/2, yCenter = (float)Screen.height/2;
float iangle;
float iiangle;
float mAngle = 0.0f;
float[] spriteX = new float[7];
float[] spriteY = new float[7];
bool jumpFlag, otherMenu;
string outputString;
public GUIStyle nhpFont;
public Texture tItems, tSave, tLoaf, tOptions, tParty, tQuests, tQuit, tBlack;
Rect rItems, rSave, rLoad, rOptions, rParty, rQuests, rQuit, rTest;
Rect rBlack;
void Awake()
{
nhpFont.contentOffset = new Vector2(xCenter, yCenter);
}
// Use this for initialization
void Start () {
iiangle = (360) / 7;
for (int a = 1; a <= 7; a++)
{
iangle = (((2*Mathf.PI) / 7) * a) + (mAngle * Mathf.Deg2Rad);
oX = Mathf.Cos(iangle) * mScale;
oY = Mathf.Sin(iangle) * mScale;
mX = xCenter + oX;
mY = yCenter + oY;
spriteX[a - 1] = mX;
spriteY[a - 1] = mY;
}
rItems = new Rect(spriteX[0], spriteY[0], 40, 35);
rSave = new Rect(spriteX[1], spriteY[1], 44, 42);
rLoad = new Rect(spriteX[2], spriteY[2], 42, 42);
rOptions = new Rect(spriteX[3], spriteY[3], 42, 42);
rParty = new Rect(spriteX[4], spriteY[4], 42, 42);
rQuit = new Rect(spriteX[5], spriteY[5], 42, 42);
rQuests = new Rect(spriteX[6], spriteY[6],42, 42);
rBlack = new Rect(0,0, Screen.width, Screen.height);
StartCoroutine(MenuNavigate(iiangle * 4, 0, 0.5f));
StartCoroutine(MenuExpand(1.0f, 100.0f));
}
//Main update function
void Update()
{
for (int a = 1; a <= 7; a++)
{
iangle = (((2*Mathf.PI) / 7) * a) + ((mAngle - 90) * Mathf.Deg2Rad);
oX = Mathf.Cos(iangle) * mScale;
oY = Mathf.Sin(iangle) * mScale;
mX = xCenter + oX;
mY = yCenter + oY;
spriteX[a - 1] = mX;
spriteY[a - 1] = mY;
}
if (!otherMenu) //If there are no other menus on the screen.
{
//iiangle*selection
TransformSprite(spriteX, spriteY);
if (Input.GetButtonDown ("Horizontal"))
{
if (Input.GetAxisRaw("Horizontal") == 1)
{
StartCoroutine(MenuNavigate(iiangle*selection, iiangle * (selection + 1), 0.2f));
if (selection < 6)
{
selection++;
}
else {
selection = 0;
}
} else if (Input.GetAxisRaw("Horizontal") == -1)
{
StartCoroutine(MenuNavigate(iiangle*selection, iiangle * (selection - 1), 0.2f));
if (selection > 0)
{
selection--;
}
else {
selection = 6;
}
}
}
outputString = getMenuItem();
}
}
//Get the selected menu item
public int getSelection()
{
return selection;
}
string getMenuItem()
{
string menuItem = "";
switch (selection)
{
case 0:
menuItem = "Quests";
break;
case 1:
menuItem = "Quit Game";
break;
case 2:
menuItem = "Manage Party";
break;
case 3:
menuItem = "Options";
break;
case 4:
menuItem = "Load Game";
break;
case 5:
menuItem = "Save Game";
break;
case 6:
menuItem = "Items";
break;
}
return menuItem;
}
//This is what moves the icons in the 360/7 angle.
IEnumerator MenuNavigate(float start, float end, float duration)
{
float startTime = Time.time;
while (Time.time - startTime < duration)
{
mAngle = Mathf.LerpAngle(start, end, (Time.time - startTime)/duration);
yield return 0;
}
}
//This pushes the icons from the center of the screen in a spiral fashion
IEnumerator MenuExpand(float start, float end)
{
float startTime = Time.time;
while(Time.time - startTime <= 0.7f)
{
mScale = (int)Mathf.Lerp(start, end, (Time.time - startTime)/0.5f);
yield return 0;
}
}
void TransformSprite(float[] x, float[] y)
{
rItems.x = x[0];
rItems.y = y[0];
rSave.x = x[1];
rSave.y = y[1];
rLoad.x = x[2];
rLoad.y = y[2];
rOptions.x = x[3];
rOptions.y = y[3];
rParty.x = x[4];
rParty.y = y[4];
rQuit.x = x[5];
rQuit.y = y[5];
rQuests.x = x[6];
rQuests.y = y[6];
}
// Update is called once per frame
void OnGUI () {
GUI.color = new Color(1.0f,1.0f,1.0f,0.5f);
GUI.DrawTexture(rBlack,tBlack,ScaleMode.StretchToFill);
GUI.DrawTexture(rItems,tItems);
GUI.DrawTexture(rSave,tSave);
GUI.DrawTexture(rLoad,tLoaf);
GUI.DrawTexture(rOptions,tOptions);
GUI.DrawTexture(rParty,tParty);
GUI.DrawTexture(rQuit,tQuit);
GUI.DrawTexture(rQuests,tQuests);
GUI.color = new Color(1.0f,1.0f,1.0f,1.0f);
GUILayout.Label(outputString, nhpFont);
GraphicsChange(selection);
}
//Switching from semi-transparency to opaque icons
void GraphicsChange(int num)
{
switch (num)
{
case 0:
GUI.color = new Color(1.0f,1.0f,1.0f,1.0f);
GUI.DrawTexture(rQuests,tQuests);
break;
case 1:
GUI.color = new Color(1.0f,1.0f,1.0f,1.0f);
GUI.DrawTexture(rQuit,tQuit);
break;
case 2:
GUI.color = new Color(1.0f,1.0f,1.0f,1.0f);
GUI.DrawTexture(rParty,tParty);
break;
case 3:
GUI.color = new Color(1.0f,1.0f,1.0f,1.0f);
GUI.DrawTexture(rOptions,tOptions);
break;
case 4:
GUI.color = new Color(1.0f,1.0f,1.0f,1.0f);
GUI.DrawTexture(rLoad,tLoaf);
break;
case 5:
GUI.color = new Color(1.0f,1.0f,1.0f,1.0f);
GUI.DrawTexture(rSave,tSave);
break;
case 6:
GUI.color = new Color(1.0f,1.0f,1.0f,1.0f);
GUI.DrawTexture(rItems,tItems);
break;
}
}
//When the menu is deactivated...
public void removeMenu()
{
StartCoroutine(MenuNavigate(iiangle*selection, (iiangle*selection - 179), 0.5f));
StartCoroutine(MenuExpand(100.0f, 1.0f));
//yield return 0;
}
}