make speed down for prefab - c#

public class a : MonoBehaviour
{
private float speed;
void Start()
{
speed=1;
}
void Update()
{
this.transform.Translate (Vector2.right * speed * Time.deltaTime);
animator.Play ("gub");
}
public void button ()
{
speed = 6f;
}
}
When I press button , I'd like to change the objects speed which are prefab.
The first prefab's speed changes... but the rest do not change.
What is wrong?

You are changing a variable of an instance of a GameObject, not a prefab.
A prefab is like a blueprint of a GameObject, so most of the data will be copied to each instance of that GameObject. But all the code that you write is referent to each instance, in that way each object will move freely from one to another, imagine if every time that you made a change in a GameObject variable, like its life, all the other instances changed the life together, it would be a mess.
To solve your problem you will need to get the information from that variable from a common place, something like a LevelManager, a place were every instance of the object can get the same value, it can be a static field in some object or a field in a Singleton, that depends on the structure of your game.

Related

How to make Instantiated Game Objects script act separately for every object. Unity2D

I have a script for that Instantiates 2 game object but when something happens to one of them it also happens to the another one even when the conditions are not met for it. How can I make the script act separately for every Game Object?
GO script:
private Transform target;
public float speed = 2f;
private Animator anim;
public float H2Damage = 5f;
private healthBar Hp;
void Start()
{
target = GameObject.FindGameObjectWithTag("enemy").GetComponent<Transform>();
anim = gameObject.GetComponent<Animator>();
Hp = GameObject.FindGameObjectWithTag("enemy").GetComponentInChildren<healthBar>();
}
void Update()
{
target = GameObject.FindGameObjectWithTag("enemy").GetComponent<Transform>();
if (Hp.Died == true)
{
Hp.Died = false;
anim.SetBool("Hero2Attack", false);
anim.SetBool("Hero2Move", true);
}
if (!target || this.anim.GetCurrentAnimatorStateInfo(0).IsName("Hero2ATTACK"))
return;
transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
anim.SetBool("Hero2Move", true);
}
private void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.CompareTag("enemy"))
{
anim.SetBool("Hero2Attack", true);
healthBar hp = col.transform.GetComponent<healthBar>();
hp.GiveDamage(H2Damage);
}
}
I believe they act the same way because they are getting the same GetComponentWithTag(), so they will Get the same objects. You also instantiate the animator, which is the exact same one, so they will do the same things. --> If it was as simple as changing the position by 1 meter per second, they would have different behavior (ie. be at different positions) But.... If you instantiate it, the current position is also instantiated, so you are going to have to get the current postion and set it to what you want, so both of these moving boxes aren't at the exact same position. You will have to do something similar here, you are going to want to either (create different scripts for the objects, or set the script values to different things)
TL;DR: You are copying the exact same script with the exact same components, so they will act similarly.
Fix: The only way to fix this is by setting their values after you instantiate them using GetComponent<>()or changing the script you assign them. (or any components for that matter)
Let me know if you have any problems or questions in the comments! :)

Objects Speed up when they move out of scene

I am new to unity and have begun trying to recreate 'flappy bird' from scratch. The pipes when the move out of the game view, speed up then slow down.
Here is the code for the pipes:
public class PipeMoving : MonoBehaviour
{
public float slideSpeed = 5f;
void Update()
{
GetComponent<Rigidbody2D>().AddForce(Vector2.left * slideSpeed, (ForceMode2D)ForceMode.Impulse);
}
}
I guess the reason why your object is slowing down is because you used force mode impulse, which will initially apply that force only once.... In order to fix it do ForceMode2D.Force, which will apply a constant force on that object.
Make the variable private and use SerializeField so it can be visible in the inspector panel and not accessed anywhere else...
[SerializeField]
private float slideSpeed = 5f;
void Awake()
{
myBody = GetComponent<Rigidbody2D>();
}
void Update()
{
move();
}
void move()
{
myBody.AddForce(new Vector2.left(slideSpeed,0), ForceMode2D.Force);
}
Set a variable myBody( or anything you prefer) as the rigidbody component so you can use it multiple times in your code more efficiently...
**Edits listed below:
I have included the keyword 'new' before Vector2.left(slideSpeed,0)
I did that because there is no pre-existing vector which is Vector2.left(slideSpeed,0) so you have to use the keyword new whenever you are declaring a vector for the first time.
If you are considering to reuse the vector, then you can declare it in the top of your code...
leftVector = new Vector2.left(slideSpeed,0);
On doing so, you don't have to use the new keyword when you will use the variable later, incase that confuses you...

unity 3d make object follow player

I want to make a robot on unity3D. I want to make the gripper of the robot when collide with object attach the gripper. So the object will follow the gripper.
What will be added to this script in order to make some thing like this?
private Rigidbody gripper;
void Start()
{
gripper_part01 = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKey("a"))
gripper.AddForce(transform.forward * 100);
}
void OnCollisionEnter(Collider obj1)
{
// how to make obj1 follow the gripper
}
It can be done by various methods. But the simplest would be making the obj1 child of gripper as soon it collides.
code will look some thing like this
void OnCollisionEnter(Collider obj1)
{
// how to make obj1 follow the gripper
obj1.transform.parent = gripper.transform;
}
Look into the state machine pattern
http://gameprogrammingpatterns.com/state.html
You'll want to create 2 states:
Not Following(Default)
Following
When the player enters the collider, switch the state to following. I'm not going to write you an entire state machine/state switching architecture for you to copy & paste, but I can tell you that you're going to want to make the states themselves a MonoBehavior class, and the actual StateMachine will not have any parent classes and will be attached to the object's controllers.
Then, you'll want to keep track of the player's coordinates like so
Vector3 playerPosition;
void OnCollisionEnter(Collider obj1)
{
if(obj1.gameObject.tag == "Player"){
playerPosition = obj1.transform.position;
myStateMachine.switchState("Follow"); //obviously replace this with your own state machine code
}
}
Make sure the player's gameObject actually has the "Player" tag in the Unity editor.

Cannot apply indexing[] to an expression of type GameObject

I've got 3 empty Gameobjects in my scene that im trying to spawn objects on, i've written this script to have a RNG value between the spawners for the object to spawn.
I've run into a problem and im not too sure how to resolve it
public class Spawns : MonoBehaviour
{
public GameObject SpawnedObject;
public bool StopSpawn = false;
public float SpawnTime;
public float SpawnDelay;
public GameObject[] SpawnPoints;
int Randomint;
// Start is called before the first frame update
void Start()
{
InvokeRepeating("SpawnObjects", SpawnTime, SpawnDelay);
}
public void SpawnObjects()
{
Randomint = Random.Range(0, SpawnPoints.Length);
Instantiate(SpawnedObject[Randomint], transform.position, transform.rotation);
if (StopSpawn)
{
CancelInvoke("SpawnObjects");
}
}
}
You are trying to use an index on a single GameObject reference.
Since you pick the random value using SpawnPoints.Length and following your description you actually rather want to get an element of the array SpawnPoints instead.
Further you say
I've got 3 empty Gameobjects in my scene that im trying to spawn objects on
but that's not what your code would do.
You probably rather wanted to use
Instantiate(SpawnedObject, transform.position, transform.rotation, SpawnPoints[Randomint].transform);
See Instantiate and in your specific case the overload
public static Object Instantiate(Object original, Vector3 position, Quaternion rotation, Transform parent);
The first parameter is the original prefab/object to spawn, the last parameter is the optional parent Transform where to spawn to.
You also might want to rethink your provided values for position and rotation .. do you really want to spawn the object at the position and rotation of the object your script is attached to? Would you not rather want them to get spawned at the position and rotation of the according spawn point? ;)

Collision working, particle fx not so much C#

I'll keep this brief and a bit short, but I currently have a particle system that seems to not be rendering even though my collision works.
I have trouble understanding other peoples work so I have not been able to find a solution I can understand.
Here is my code:
public float speed;
public Rigidbody rb;
public int health;
private float knockback;
private float knockup;
public ParticleSystem Eparticle; //*** variable for particle system ***
// Use this for initialization
void Start()
{
rb = GetComponent <Rigidbody>();
knockback = 100f;
knockup = 250f;
}
void OnCollisionEnter(Collision col)
{
if (col.gameObject.name == "enemy")
{
health = health - 20;
rb.AddRelativeForce(Vector3.back * knockback);
rb.AddRelativeForce(Vector3.up * knockup);
Destroy(col.gameObject);
Instantiate(Eparticle);
}
if (col.gameObject.name == "endgoal")
{
SceneManager.LoadScene("level 1");
}
}
What am I doing wrong with my instantiate(Eparticle) line?
Could someone please talk me through a solution?
Thank You :)
You should invoke the Instantiate method at the position where you want the particle prefab to appear.
You could do something like this...
Instantiate(Eparticle,transform.position,transform.rotation);
Actually, you can also create (instantiate) a GameObject at runtime as follows...
GameObject obj= Instantiate(Eparticle,transform.position,transfrom.rotation) as GameObject;
This way, you have some sort of 'control' over the instantiated gameobject.
For instance, you can destroy the object after using it by calling the Destroy() method.
E.g.:
Destroy(obj,2f);//Destroys the created object after 2 seconds.
Of course, this is not a good way to go about it if you are going to be instantiating and destroying a lot of objects. You should read about Object Pooling for this purpose.

Categories

Resources