- Home /
I have array of gameobject. How can i make a class/es with options for each gameobject in the array ?
This is what i tried so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public struct SpinableObject
{
public Transform t;
public float rotationSpeed;
public float minSpeed;
public float maxSpeed;
public float speedRate;
[HideInInspector]
public bool slowDown;
}
public class SpinObject : MonoBehaviour
{
private bool slowDown = false;
public float rotationSpeed;
public float slowdownMax;
public float slowdownMin;
public GameObject[] objectsToRotate;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
for (int i = 0; i < objectsToRotate.Length; i++)
{
SpinableObject spinableObject = objectsToRotate[i];
if(spinableObject.rotationSpeed > spinableObject.maxSpeed)
spinableObject.slowDown = true;
else if (spinableObject.rotationSpeed < spinableObject.minSpeed)
spinableObject.slowDown = false;
spinableObject.rotationSpeed = (spinableObject.slowDown) ? spinableObject.rotationSpeed - 0.1f : spinableObject.rotationSpeed + 0.1f;
spinableObject.t.Rotate(Vector3.forward, Time.deltaTime * spinableObject.rotationSpeed);
}
}
}
But i'm getting error on:
SpinableObject spinableObject = objectsToRotate[i];
The error is on the: objectsToRotate[i]
Cannot implicitly convert type 'UnityEngine.GameObject' to 'SpinableObject'
So first how can i fix the error ?
Second how can i make it instead using struct to use two classes:
A class with its own function to manage the rotation and another one to indicate whether the object should accelerate or decelerate
Answer by UnityCoach · Jul 22, 2017 at 11:45 PM
I would rather have SpinableObject as a MonoBehaviour on every object you want to rotate. Then, if you want to sync' them, you can use some kind of Manager to which they can subscribe to events, or receive method calls.
Can you show me please some example or how to start doing it ?
This is the code i'm using now:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SpinableObject
{
[SerializeField]
private Transform t;
[SerializeField]
private float rotationSpeed;
[SerializeField]
private float $$anonymous$$Speed;
[SerializeField]
private float maxSpeed;
[SerializeField]
private float speedRate;
private bool slowDown;
public void Rotate()
{
if (rotationSpeed > maxSpeed)
slowDown = true;
else if (rotationSpeed < $$anonymous$$Speed)
slowDown = false;
rotationSpeed = (slowDown) ? rotationSpeed - 0.1f : rotationSpeed + 0.1f;
t.Rotate(Vector3.forward, Time.deltaTime * rotationSpeed);
}
}
public class SpinObject : $$anonymous$$onoBehaviour
{
private bool slowDown = false;
public float rotationSpeed;
public float slowdown$$anonymous$$ax;
public float slowdown$$anonymous$$in;
public SpinableObject[] objectsToRotate;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
for (int i = 0; i < objectsToRotate.Length; i++)
{
objectsToRotate[i].Rotate();
}
}
}
@UnityCoach : Can you explain why a $$anonymous$$onoBehaviour would be preferable ins$$anonymous$$d a "standard" class ? I've always thought $$anonymous$$onoBehaviour adds an additional "heavy" layer, which can be avoided here.
Well, this is paradigm opinion really, I usually find it more natural when an object controls itself, yet sync'ing with others with some $$anonymous$$anager class when needed, rather than being controlled by another. If you have thousands of objects, then maybe there's a difference, but you can't really tell for sure until you benchmark this. $$anonymous$$onoBehaviours are quite optimised, you can turn them off when you don't need them, etc. Also, storing all the objects in a big List and go through that list every Update cycle, this is what the Engine does.
Answer by Hellium · Jul 22, 2017 at 10:27 PM
public GameObject[] objectsToRotate
must be
public SpinableObject[] objectsToRotate
This is working now. but i'm not sure if it's a good way. This is what i ended with so far:
But i guess making a loop(FOR) inside the Update is a bad idea ? (as the function is called every frame and the for loop would be activated every frame lowering the fps drastically). $$anonymous$$aybe there should be some IF there or something else ?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SpinableObject
{
[SerializeField]
private Transform t;
[SerializeField]
private float rotationSpeed;
[SerializeField]
private float $$anonymous$$Speed;
[SerializeField]
private float maxSpeed;
[SerializeField]
private float speedRate;
private bool slowDown;
public void Rotate()
{
if (rotationSpeed > maxSpeed)
slowDown = true;
else if (rotationSpeed < $$anonymous$$Speed)
slowDown = false;
rotationSpeed = (slowDown) ? rotationSpeed - 0.1f : rotationSpeed + 0.1f;
t.Rotate(Vector3.forward, Time.deltaTime * rotationSpeed);
}
}
public class SpinObject : $$anonymous$$onoBehaviour
{
private bool slowDown = false;
public float rotationSpeed;
public float slowdown$$anonymous$$ax;
public float slowdown$$anonymous$$in;
public SpinableObject[] objectsToRotate;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
for (int i = 0; i < objectsToRotate.Length; i++)
{
objectsToRotate[i].Rotate();
}
}
}
Don't worry, a simple for loop won't make your FPS drop. Except if you have thousand objects in your array.
Your answer
Follow this Question
Related Questions
Why InputField don't have the property text ? 2 Answers
How can i change the walls height and keep the size for example 100x100 but height 0.1 ? 1 Answer
How can i using a break point if a gameobject have a collider after added to it ? 1 Answer
How can i get all childs from List ? 3 Answers
How can i set the same script on two GameObjects so the script will work on both objects same time ? 1 Answer