C# Unity dot syntax exercise correct solution?
I'm a noob in C# and Unity aspect so please have mercy.
I'm doing an exercise on dot syntax which requires me to have two GameObjects and two scripts.
First script:
using UnityEngine;
using System.Collections;
public class Spinner : MonoBehaviour
{
public void SpinLeft()
{
transform.Rotate(0,0,60 * Time.deltaTime);
}
public void SpinRight()
{
transform.Rotate(0,0,-60 * Time.deltaTime);
}
}
Second script:
using UnityEngine;
using System.Collections;
public class LearningScript : MonoBehaviour
{
GameObject capsuleGO;
Spinner cubeComp;
void Start()
{
capsuleGO = GameObject.Find("Capsule");
Debug.Log(capsuleGO);
cubeComp = GameObject.Find("Cube").GetComponent<Spinner>();
Debug.Log(cubeComp);
}
void Update()
{
if(Input.GetKey(KeyCode.LeftArrow))
{
capsuleGO.GetComponent<Spinner>().SpinLeft();
}
if(Input.GetKey(KeyCode.RightArrow))
{
capsuleGO.GetComponent<Spinner>().SpinRight();
}
if(Input.GetKey(KeyCode.UpArrow))
{
cubeComp.SpinLeft();
}
if(Input.GetKey(KeyCode.DownArrow))
{
cubeComp.SpinRight();
}
}
}
On the Second script I was asked to make this portion of it:
if(Input.GetKey(KeyCode.LeftArrow))
{
capsuleGO.GetComponent<Spinner>().SpinLeft();
}
and turn it into something like this ↓ where I didn't have to write the extra "GetComponent..."
if(Input.GetKey(KeyCode.UpArrow))
{
cubeComp.SpinLeft();
}
Exercise Question: is there a way to code it so that it doesn't have to access "Spinner" by assigning a new variable called "capsuleComp" that stores a reference to "Spinner" Component instead of using "capsuleGO"?
My solution to this was this code whereby I made an exact "Spinner" script and named it "Spinner2" and attached it to the same two GameObjects then changed the code to ↓:
using UnityEngine;
using System.Collections;
public class LearningScript : MonoBehaviour
{
Spinner cubeComp;
Spinner2 capsuleComp;
void Start()
{
capsuleComp = GameObject.Find ("Capsule").GetComponent <Spinner2>();
Debug.Log(capsuleComp);
cubeComp = GameObject.Find("Cube").GetComponent<Spinner>();
Debug.Log(cubeComp);
}
void Update()
{
if(Input.GetKey(KeyCode.LeftArrow))
{
capsuleComp.SpinLeft();
}
if(Input.GetKey(KeyCode.RightArrow))
{
capsuleComp.SpinRight();
}
if(Input.GetKey(KeyCode.UpArrow))
{
cubeComp.SpinLeft();
}
if(Input.GetKey(KeyCode.DownArrow))
{
cubeComp.SpinRight();
}
}
}
My question: Is this the right way to do it in terms of coding (functionality wise and efficiency wise)?
I feel like I didn't understand the main concept of the exercise but managed to find a solution somehow...Any pointers would be much appreciated since I'm since in my learning phase of C# and Unity. Thanks in advance and sorry for the long post...
Answer by LazyElephant · Jan 10, 2016 at 08:33 AM
I may be misunderstanding your solution, but it sounds like you directly copied the spinner script so that both game objects now have a spinner and a spinner2? This is bad design, since you have two classes doing the exact same thing.
It seems that the exercise was more to see if you understood how to access a component using the Find()
and getComponent<T>()
methods so that you could reference it in your script. It is a good idea to do this in the start() method of your scripts once for each object you have to find and store it in a variable in your class. It is more efficient and, if you have to call these types of search functions very often in your update()
methods, you run the risk of slowing down your game.
For the solution, one thing you need to understand is that, even though you only wrote the script once, each game object has it's own copy of it when you add it as a component. So to get the spinner component for the CapsuleGO, you simply create another Spinner variable in your class and store the CapsuleGO spinner in it in your Start()
function. This would then allow you to reference it with variable.function()
.
using UnityEngine;
using System.Collections;
public class LearningScript : MonoBehaviour
{
Spinner cubeComp;
Spinner capsuleComp;
void Start()
{
capsuleComp = GameObject.Find("Capsule").GetComponent<Spinner>();
Debug.Log(capsuleComp);
cubeComp = GameObject.Find("Cube").GetComponent<Spinner>();
Debug.Log(cubeComp);
}
void Update()
{
if(Input.GetKey(KeyCode.LeftArrow))
{
capsuleComp.SpinLeft();
}
if(Input.GetKey(KeyCode.RightArrow))
{
capsuleComp.SpinRight();
}
if(Input.GetKey(KeyCode.UpArrow))
{
cubeComp.SpinLeft();
}
if(Input.GetKey(KeyCode.DownArrow))
{
cubeComp.SpinRight();
}
}
}
The fact that you made a workable answer is good. It means you can think around a problem. With more experience and language specific knowledge, you'll be able to create better solutions in the future.
Nope, you did not misunderstood my solution. That's exactly what I did LOL...Yes, I felt it was bad practice design that's why I felt I had to find the proper solution to it (I tested it and it ran perfectly!) and you handed that very solution to me. Thank you so much for taking the time to answer my question! I kept thinking and trying but I just couldn't figure it out!
lol...I was VERY glad when I found the workaround solution but something just didn't feel right about it.
I have another question though...How was it possible to assign "Spinner" to two different variables? Is it because "Spinner" is just a function/method?? I thought that wasn't possible and would definitely give me an error.
The spinner script you wrote was just the class definition. You can have as many instances of a class as you like. By adding the script to both the cube and capsule, you instantiated two separate instances of the class, so all you needed were the two variables to store references to them.
Okay...I think I need to read more and drill the different definitions to my head...
Thanks again!