1 回答
TA贡献1780条经验 获得超4个赞
// The [Range()] attribute will make `speed` show up with a slider in the inspector
[Range(0.1f, 5)]
public float speed = 3;
public Sprite[] Pokemons;
private SpriteRenderer sr;
private float worldMiddleX;
private float worldLeftX;
private float worldRightX;
private int currentPokemon = 0;
private float secondsInMiddle = 3f;
void Start()
{
sr = GetComponent<SpriteRenderer>();
sr.sprite = Pokemons[currentPokemon];
// Find out what X's in the world the left edge, middle & right of the screen is,
// if you have a 1920x1080 resolution Screen.width will be 1920. But we don't
// want to position us at x = 1920, because that is FAR away
// So we need to figure out where in the GAME world, our screen right edge is
worldMiddleX = Camera.main.ScreenToWorldPoint(new Vector2(Screen.width / 2, 0f)).x;
// +100 & -100 because we want it to go outside of the screen a little bit
// These should be tweaked based on the sprite width
// Can be done dynamically / programatically too. Their width is in
// Pokemons[0].rect.width
worldLeftX = Camera.main.ScreenToWorldPoint(new Vector2(-100, 0f)).x;
worldRightX = Camera.main.ScreenToWorldPoint(new Vector2(Screen.width + 100, 0f)).x;
// Start our endlessly looping Coroutine, which will take care of
// 1. Moving to the middle.
// 2. Waiting in middle
// 3. Moving outside of screen to the left & resetting position
// 4. Repeat
StartCoroutine(SlideLeftButWaitMiddleEndlesslyLoop());
}
/*
* Changed from void to IEnumerator to get access to the
* `yield` keyword, which will let us pause execution for X seconds.
* If you do this with a normal method, you will need to invoke it with
* `StartCoroutine()` as it becomes a Coroutine, which will execute in
* an asynchronous manner
*/
IEnumerator SlideLeftButWaitMiddleEndlesslyLoop()
{
while (true)
{
// yield return *Coroutine* will make sure that the code doesn't continue
// its code path until it has completed its Coroutine (method execution)
// Wait for MoveToMiddle() to finish executing
yield return StartCoroutine(MoveToMiddle());
// Wait for x seconds
yield return new WaitForSeconds(secondsInMiddle);
// Wait for MoveOutsideScreenAndReset() to finish executing
yield return StartCoroutine(MoveOutsideScreenAndReset());
}
}
IEnumerator MoveToMiddle()
{
while (transform.position.x > worldMiddleX)
{
transform.Translate(-(speed * Time.deltaTime), 0f, 0f);
yield return null;
// yield return null here will make this loop pause until next frame
// so that it doesn't just do all the loops instantly and teleport your sprite
}
}
IEnumerator MoveOutsideScreenAndReset()
{
while (transform.position.x > worldLeftX)
{
transform.Translate(-(speed * Time.deltaTime), 0f, 0f);
yield return null;
// yield return null here will make this loop pause until next frame
// so that it doesn't just do all the loops instantly and teleport your sprite
}
// Change to the next sprite
nextPokemonSprite();
// Reset the position, then the Update() method will start again from the top
// since this method will have fully executed
Vector3 pos = transform.position;
pos.x = worldRightX;
transform.position = pos;
}
// If we're at the last Pokemon in the Pokemons array, start over at 0
void nextPokemonSprite()
{
currentPokemon++;
if (currentPokemon == Pokemons.Length)
currentPokemon = 0;
sr.sprite = Pokemons[currentPokemon];
}
- 1 回答
- 0 关注
- 112 浏览
添加回答
举报