Help with Cut-downable tree understanding classes

Ok,

This script should cause my tree to be destroyed and replaced by a ‘stump’ after it has been clicked and held upon for 5 seconds.

var stump : GameObject;
var duration = 5;
private var nextCut = 0.0;

function OnMouseOver () {

    if (Input.GetMouseButton (0)  Time.time > nextFire) {
        nextCut = Time.time + duration;
        Destroy(this.gameObject);
        var stump = Instantiate (stump, transform.position, Quaternion.Euler(-90, 0, 0));
    }
}

This sort of worked, but just destroyed the tree when you clicked on it, not after 5 seconds. Anyway, I read up on classes, and realised it would make it heaps easier for me to make a tree class. (I will be accessing other variables from it later)

#pragma strict

var thisTree : GameObject;

function OnMouseOver () {
thisTree = Tree;
thisTree.Chopped;
}

class Tree
{
	var duration : float = 5;
	var stump : GameObject;
	var nextCut : float = 0;
	
	function Chopped()
	{
		if(Input.GetMouseButton(0)  Time.time > nextCut)
		{
		nextCut = Time.time + duration;
        Destroy(this.gameObject);
		var stump = Instantiate(stump,transform.position,Quaternion.Euler(-90,0,0));
		}
	}
}

But this gave my a whole heap of errors, which I don’t understand. For example, I get an error for Destroy(this.gameObject); << Is it a problem for me to be accessing other built-in classes within another class?
Anyway, this is my first (Proper) attempt at building a class.

Thanks in advance.

EDIT: Also, if I just have a script with a class in it – with nothing else, can I access it remotely? Example: Class ‘Destroy’, is a built in class, but can be called through Destroy(this.gameObject); or somesuch. Can I do this in classes I have made?

For your Destroy(this.gameObject) error you can just do Destroy(gameObject). It will destroy the gameobject the script is attached to.

At least it should, sorry if you still get the error. I don’t usually make classes, which is probably bad programming but the framework for my game was started when I was just a noob so it’s messed up a lot and I have to work with it.

A few things:

  • Destroy is not a class - it’s a method. UnityEngine.Object is a class that has a method named Destroy.
  • Destroy(gameObject) or Destroy(this.gameObject) will only work on classes the derive from UnityEngine.Component
  • Don’t mix MonoBehaviour and non-MonoBehaviour classes in the same file and don’t put more than 1 MonoBehaviour class in a file.

To answer your original question question of why does the stump get destroyed instantly because when your if statement is ran Time.time is greater(>) than next cut since nextCut is zero(0) which is what you wanted but you haven’t told the code block to delay before destroying the tree and instantiating the stump.

What you want to do is use a

yield WaitForSeconds (5);

statement inside the if block to delay the tree being destroyed and the prefab being instantiated. Click wait for seconds for more info on yield. But this isn’t a good way to do it either to achieve exactly what you want.

Sorry if I sound noobish, but whats the difference between a MonoBehaviour class and a non-MonobBehaviour class? Also, is there a way to declare the class so that it can support a non-Monobehaviour class?

Ok, I would’ve done this but this cuts down the tree whether or not I have clicked and held. I am trying to cut down a tree after I have clicked and held on it for 5 seconds. (Think Minecraft)

Accidental post

Don’t mix these in the same file:

public class TheClass : MonoBehaviour
{
    // this class inherits from MonoBehaviour
    // Destroy will work on this
}
public class TheClass
{
    // this class does not
    // Destroy does not work on this
}

I know I’ve said that… You have to manually set the timer to know how long its been since you’ve pressed the button…

One question is why do you not need a MonoBehaviour? There is a lot of infrastructure that comes with being derived from a MonoBehaviour. Check the docs for everything this base class gives you. If you simply declare your own class, you give all of that up and would have to implement it yourself, and somehow hook it back in.

As to your scripting question, I would have 2 boolean flags and one float member to keep track of time.
One flag is for showing if cutting is allowed.
One flag is for showing if the cutting is actually happening.
I would do something similar to this:

var isCuttingValid : boolean = false;
var isCutting : boolean = false;
var startOfCut : float = 0f;

function OnMouseEnter ()
{
   isCuttingValid = true;
}

function OnMouseExit ()
{
   //reset all the flags
   isCuttingValid = false;
   isCutting = false;
}

function Update ()
{
   if (Input.GetMouseButtonDown(0)  isCuttingValid) {
      isCutting = true;
      startOfCut = Time.time;
   } else if (Input.GetMouseButtonUp(0)  isCutting  (Time.time - startOfCut) >= duration) {
      //reset flags
      isCutting = false;
      isCuttingValid = false;
      //do the object swap here or call another function that does it
   }
}

Hope this helps

Thanks, this helps heaps - also helps me understand a couple of other key functions.

What makes you say this? What exactly is wrong with the following code?

public class MyClass : MonoBehaviour
{
    public DataClass[] myDataClassArray;
}

[System.Serializable]
public class DataClass
{
    public int testInt;
    public float testFloat;
}

I know it’s bad practice to put multiple classes in the same file. But I’m wondering if there is something semantically wrong with it, or if it’s just frowned upon?

Unity doesn’t recognize it as a MonoBehaviour in your project so you can’t drag and drop onto a GameObject. Other than that, it works fine. :slight_smile:

Can’t replicate this, can attach them to gameobjects just fine.

Essentially all that script does is create an array of DataClass objects. The class MyClass still inherits from MB, it just contains instances of a script that doesn’t, which is fine.

After doing some quick testing, it seems it doesn’t matter whether the MB derived class is defined first in the script, and any inheritance on the “DataClass” class doesn’t create any issues. (I’m not saying creating multiple classes in one script is ok btw, just saying that it doesn’t cause any functional issues).

I think Kelso was saying that the non-MB classes are not draggable onto objects in the inspector.

I think it’s OK to have multiple classes in one file as long as only one is a MB derived one.

This Unity Answers page answers this question very well.

Its mostly that its “bad practice” to have different classes in the same file, no big practical trouble.