- Home /
c# script not doing anything.
Hi, I'm trying to write a simple script through experimenting and what not. I wanted to make a script that moves a 2d object around without player input. In this case i called the class enemyMovement, but the script in its simplest form would have been for things like making clouds that move about etc. Here's the code:
using UnityEngine;
using System.Collections;
public class enemyMovement : MonoBehaviour {
float move = 5;
public float distance = 0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update ()
{
eneMove ();
}
void eneMove()
{
while (distance < 50)
{
transform.Translate (-Vector2.right * move * Time.deltaTime);
distance++;
}
if (distance == 50)
{
while(distance > 0)
{
transform.Translate (Vector2.right * move * Time.deltaTime);
distance--;
}
}
}
}
I have attactched the code to an object (spheres count as objects yes?) but other than at first when the sphere jumped miles off the screen in one go, it doesn't move at all now. Any ideas on how to make it work how I intended it to would be great.
Thanks for your time.
Answer by robertbu · Feb 23, 2014 at 06:09 AM
You have a couple of issues here. The most pressing is that you are making your while loops happen in a single frame. This causes all the movement to happen at once. One fix for your code would be to only call 'eneMove()' once, and to make the whole method into a Coroutine. Exmaple:
using UnityEngine;
using System.Collections;
public class Bug25a : MonoBehaviour {
float move = 5;
public float distance = 0f;
void Start ()
{
StartCoroutine(eneMove());
}
IEnumerator eneMove()
{
while (true)
{
while (distance < 50)
{
transform.Translate (-Vector2.right * move * Time.deltaTime);
distance++;
yield return null;
}
while(distance > 0)
{
transform.Translate (Vector2.right * move * Time.deltaTime);
distance--;
yield return null;
}
}
}
}
But this revised code still has a potential issue. You are measuring your 'distance' by incrementing a variable each frame. In other words, 'distance' is just an frame counter with no map to any real distance. Since the 'deltaTime' of individual frames differ, this code will cause your object to walk around on the 'x' axis some.
Here is an alternate solution for getting an object to move back and forth. It uses Mathf.PingPong():
using UnityEngine;
using System.Collections;
public class Swinging : MonoBehaviour {
public Vector3 minPos = new Vector3(-5.0f, 0.0f, 0.0f);
public Vector3 maxPos = new Vector3( 5.0f, 0.0f, 0.0f);
public float speed = 1.0f;
void Update()
{
transform.position = minPos + (maxPos - minPos) * Mathf.PingPong(Time.time * speed, 1.0f);
}
}
Note if you want a more natural feel to the swinging back and forth, you can use Mathf.Sin() in the positioning. Replace the one line of code in Update() with:
transform.position = minPos + (maxPos - minPos) * (Mathf.Sin(Time.time * speed) + 1.0f) / 2.0f;
Thanks a lot man, really detailed/thorough answer. You've helped me out a lot. :)
Answer by zharik86 · Feb 23, 2014 at 06:14 AM
Your error is simple. Look attentively at your eneMove function. In it at the same time for one frame two while of a cycle on 50 times everyone (then object will return to start state, but it everything occurs for one frame) will be executed. If you want to move your object, here for example the script is lower:
public float move = 5.0f;
public float distance = 0.0f;
private int directMove = 1; //your direct move, 1 - right, 2 - left
void Start() {
distance = 0.0f;
directMove = 1;
}
void Update() {
eneMove();
}
public void eneMove() {
if (directMove == 1) {
transform.Translate (-Vector2.right * move * Time.deltaTime);
distance++;
if(distance > 50) {
distance = 0.0f;
directMove = 2;
}
} else if (directMove == 2) {
transform.Translate (Vector2.right * move * Time.deltaTime);
distance++;
if(distance > 50) {
distance = 0.0f;
directMove = 1;
}
}
}
Somehow so. Certainly instead of conditions of if it is possible to use switch-case. I hope it to you will help.