I'm trying to give the user the option of changing the current gameObject (a cube) to a new shape (a sphere), however, I can't figure out how to carry all the functionality that I wrote for the cube over to the sphere.
I've managed to destroy the old cube and replace it with a sphere, but none of the key press controls for the cube seem to be present for the sphere. I had an idea of setting the new gameObject's methods to the ones that I used for the cube (i.e. newSphere.transform.rotation() = this.transform.rotation();), but it doesn't seem to work.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cubeControls : MonoBehaviour
{
// Constants for object rotation
public float moveSpeed = 80.0F;
public float turnSpeed = 100.0F;
// Initial scale of the original cube
public static Vector3 initscale = Vector3.one;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
/* Changing the position of the object
*
*/
// Moving the object right
if (Input.GetKey(KeyCode.D))
{
transform.Translate(Vector3.right * moveSpeed * Time.deltaTime);
}
// Moving the object left
if (Input.GetKey(KeyCode.A))
{
transform.Translate(Vector3.left * moveSpeed * Time.deltaTime);
}
/* Changing the rotation of the object
*
*/
// Rotating the cube to the right
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime);
}
// Rotating the cube to the left
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Rotate(Vector3.down, turnSpeed * Time.deltaTime);
}
// Saving the current rendered material
Renderer rend = GetComponent<Renderer>();
/* Changing the scale of the object
*
*/
// Double the size of the cube
if (Input.GetKeyDown(KeyCode.Alpha2))
{
transform.localScale += new Vector3(2F, 2F, 2F);
}
/* Changing the color via key presses
*
*/
if (Input.GetKeyDown(KeyCode.R))
{
rend.material.SetColor("_Color", Color.red);
}
// Changing to sphere
if (Input.GetKeyDown(KeyCode.X))
{
GameObject newSphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
Destroy(this.gameObject);
}
}
}
Generally with Unity we don't instantiate a primitive and add components to it by hand, doing so is generally not the best way of doing things long term, as it's hard to non-programmers to change the functionality. Worse, it requires code changes to change how anything works! Unity's main advantage is it's huge fully featured visual editor, we should use it as much as possible, otherwise what's the point in using Unity at all?
What you want to do instead, generally speaking, is create a prefab of each of these entities, the cube and the sphere, and attach the script to both. Then, rather than instantiating a primitive sphere and trying to build it from the ground up in the script, you simply call GameObject.Instantiate() to create the new sphere then and there.
public class cubeControls : MonoBehaviour
{
// Constants for object rotation
public GAmeObject spherePrefab;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.X))
{
Instantiate(spherePrefab, transform.position, transform.rotation);
}
}
}
This has a few advantages, one, you have full control over the sphere inside the editor, want to attach different components to your sphere? You can do so without having to change any code! Want to have slightly different parameters? No problem. Does an artist want to add a cool trail effect to the sphere? They can do it without programmer help.
If you need to modify variables on the sphere (e.g. to transfer, say, the cube's remaining hit points?) you can call GetComponent() on the newly instantiated sphere prefab, and call functions/edit variables as you wish.