I’ve been working on this script for about 12 hours now and I haven’t made any progress. It’s for a whack-a-mole style game.
I have 3 movement types defined in 3 functions. They each reference the MoveObject script. MoleRetreat needs to be able to interrupt MoleAscend and MoleDescend when the script recognizes a hit on the mole. Any ideas?
var moveSpeed:int = 1;
var waitTime:float = 2.0;
var moleVisible:boolean = false;
var moleHit:boolean = false;
function OnBecameVisible() {
moleVisible = true;
print(gameObject.name + "is visible");
StartCoroutine("AscendMole");
yield WaitForSeconds (waitTime);
StartCoroutine("DescendMole");
}
function AscendMole() {
yield MoveObject.use.Translation(transform, Vector3.up, moveSpeed, MoveType.Time);
}
function DescendMole() {
yield MoveObject.use.Translation(transform, -Vector3.up, moveSpeed, MoveType.Time);
bMoleVisible = false;
// Adjust stats
GameStats.moleKillsInARow = 0;
print("Moles killed in a row: " + GameStats.moleKillsInARow);
Destroy (gameObject);
}
function MoleRetreat() {
yield MoveObject.use.Translation(transform, -Vector3.up, .25, MoveType.Time);
bMoleVisible = false;
// Adjust stats
GameStats.moleKillTotal = GameStats.moleKillTotal + 1;
GameStats.moleKillsInARow = GameStats.moleKillsInARow +1;
print("Moles killed: " + GameStats.moleKillTotal);
print("Moles killed in a row: " + GameStats.moleKillsInARow);
Destroy (gameObject);
}
function Update () {
if (Input.GetKeyDown(KeyCode.KeypadEnter) && !moleHit) {
// Recognize hit
moleHit = true;
// Adjust movement
StopAllCoroutines();
StartCoroutine("MoleRetreat");
}
}
You're going about it the wrong way 'methinks' . Whack-a-mole is the classic example for a really small State Machine. I've got a 90% completed whack-a-something project over here. I'll try and strip it a bit
So our moving up coroutine only does things if it's in that state while(t < 1&&state == state_.movingUp). When you click it for example, the GameManager just calls SetState(3) and that does something like:
IEnumerator Knocked()
{
state = state_.knocked;
// insert various logic bits here
float t = 0;
while(t < 1)
{
yield return null;
t += Time.deltaTime / 0.55f;
TR.position = Vector3.Lerp(start, bottomPosition, t);
}
SetState(0);//rest
}
Notice this doesn't have a state condition, since we want the mole to not be interupted while going back into it's hole.
Ofcourse you'll be checking for specific states and things within the state switcher (SetState) itself, before starting a coroutine. For example:
if(state == state_.resting) // make sure the mole is not doing anything important
StartCoroutine(MoveUp()); // start moving
else // if mole busy
GM.GetMole() // get another random mole from the array
Eureka! Thanks azzogat! I was doing some experimenting with while loops yesterday but Unity kept crashing. I think I found something that works well.
I’m not sold on the state machine. I haven’t had any experience with enums yet, but after checking out your game, which is really cool, my plans are quite different. The code I have below is very different from what I was using (MoveObject script). If I keep going back to change things, I never get to move forward and learn from my mistakes. What I have now seems to work well so I’m going to stick with it.
var waitTime:float = 2.0;
var moleVisible:boolean = false;
var moleHit:boolean = false;
var moleKilledSpeed = 5;
var moleAliveSpeed = 1;
function OnBecameVisible() {
moleVisible = true;
StartCoroutine("MolePresents");
}
function MolePresents() {
// Mole ascends
while (transform.position.y < 1){
transform.Translate(Vector3.up * Time.deltaTime * moleAliveSpeed);
yield;
}
// Mole waits
yield WaitForSeconds (waitTime);
// Mole descends
while (transform.position.y > 0) {
transform.Translate(Vector3.down * Time.deltaTime * moleAliveSpeed);
yield;
}
Destroy (gameObject);
}
function MoleKilled() {
while (transform.position.y > 0) {
transform.Translate(Vector3.down * Time.deltaTime * moleKilledSpeed);
yield;
}
// Remove object
bMoleVisible = false;
Destroy (gameObject);
}
function Update () {
if (Input.GetKeyDown(KeyCode.KeypadEnter) && !moleHit) {
// Recognize hit
moleHit = true;
// Adjust movement
StopCoroutine("MolePresents");
StartCoroutine("MoleKilled");
}
}