Unity general questions

Comments

  • 2. is a Method on the enemy the same as a function declared, for example, "void Damage"?
    2. Yeah, to my knowledge a "method" is just C# speak for a "function". If you want to access it from another component though, you need to make it public, i.e. "public void Damage()"
    AFAIK, a function is a type of method:

    - A function is a method that has a return type.
    - A procedure is method that does not.

    So "public void Damage()" would be a procedure not a function. These are just technicalities though.
  • edited
    Method is Object Oriented speak for a function or procedure associated with an object (http://en.wikipedia.org/wiki/Method_(computer_science))

    Looking at it the other way around may make it a bit clearer. An Object is something that collects together data describing something, and methods that act on that data.

    Practically, when talking about C# code, you can safely use the terms function and method interchangeably, since there are no functions NOT associated with classes (which just describe objects). There are instance and static methods. As their names suggest, instance methods are associated with and act on a particular instance of a class (a particular object). Conversely static methods are not related to instances, and only have access to data shared across all instances of a class (static data).

    While it's not strictly necessary for you to get stuff done, when you get a chance it's worth going over Wikipedia's article on OO, it may help understand some of these distinctions: http://en.wikipedia.org/wiki/Object-oriented_programming.

    Also, because from past messages some people seem to struggle with the distinction (and Unity's choice of naming doesn't always help) and this makes understanding how everything works that bit more difficult:
    -Classes and Objects (instances of a class) are OO language concepts
    -GameObjects, Components, Prefabs and instances of prefabs are Unity concepts (and so higher level)

    While there are classes to represent most of the Unity concepts (eg there is a class GameObject), when working in Unity it helps to think primarily in terms of their higher level objects.

    I hope this helped, rather than hindered :P
  • Thanks guys! I'm going through all the reading and it does help a lot conceptually :D

    Now to apply the theory... :)
  • edited
    Hi guys

    I'm using a raycast to detect bullet vs enemy collision, but when my bullet is generated "inside" the enemy's collider, it's not detected as a hit - is there a way to have the collision detect even if it originated inside the collider?

    In fact, if a raycast gets intersected by an object that moves in parallel from the ray, it doesn't detect as a hit... So if bullet went under my ship, and the ship drops onto the bullet, the collision doesn't fire... Is there a way around this except running multiple rayscasts?

    Vector3 fwd = transform.TransformDirection(Vector3.right);
            if (Physics.Raycast(transform.position, fwd, out rayHit, 0.5f, mask)){
    			GameObject InstantiatedExplosion = Instantiate(explosion,
    									transform.position,
    									transform.rotation)
    									as GameObject;
    			rayHit.collider.gameObject.GetComponent<enemyBehaviour>().enemyLifeCurrent -=1;
    			Destroy (gameObject);
  • Why not use OnCollisionEnter()?
  • edited
    I used OnCollisionEnter to start but then when I wanted to work with layers and tags it didn't seem to work easily. Ruan (Free Lives) suggested that using raycasts for projectiles were easier and didn't have to worry about the collision matrix or physics (or something like that, I can't remember properly anymore, it was over Twitter).

    So it seems like raycasts don't work on anything parallel to it? I should go back to OnCollisionEnter?

    GAH, and OnCollisionEnter doesn't work when I move things by Translate instead of AddForce, right? I think I'm experiencing that now.... And I don't want rigidbodies all over my stuff which creates messy collisions...
  • Raycasts work fine, though I think OnCollisionEnter() is just easier to understand. you are using the raycast on your bullet to detect the collision, every bullet, every frame raycasts. might be a problem if you have tonnes of bullets flying around, not sure though. I would personally use OnCollisionEnter() on projectiles, but raycasts on a gun.

    I can't see why your bullet is created inside the enemy based on the code you have posted. have a look at where you instantiate the bullet.
    you could try to hack it :P increase the length of your raycast, then test the distance from the bullet to the hit point, and if close enough, do the stuff.

    OnCollision/TriggerEnter/stay/exit all work fine with only a collider I believe.

    also use Debug.log() to test it helps ;)
  • Just a quick question (and maybe irrelevant) but how / why do bullets originate in the enemy in the first place?
  • Raycasts work fine, though I think OnCollisionEnter() is just easier to understand. you are using the raycast on your bullet to detect the collision, every bullet, every frame raycasts. might be a problem if you have tonnes of bullets flying around, not sure though. I would personally use OnCollisionEnter() on projectiles, but raycasts on a gun.
    It would depend on the speed of the projectile, if it is moving too quickly (moving large units between each frame) some collisions won't be fired since the projectile would have not actually collided with the object.
    OnCollision/TriggerEnter/stay/exit all work fine with only a collider I believe.
    "Note that collision events are only sent if one of the colliders also has a non-kinematic rigidbody attached."
    "Note that trigger events are only sent if one of the colliders also has a rigidbody attached."
  • @CorruptedHeart
    It would depend on the speed of the projectile, if it is moving too quickly (moving large units between each frame) some collisions won't be fired since the projectile would have not actually collided with the object.
    ah, very true. but when such problems arise, prediction and guessing (interpolate and extrapolate) comes in handy.
    "Note that collision events are only sent if one of the colliders also has a non-kinematic rigidbody attached."
    "Note that trigger events are only sent if one of the colliders also has a rigidbody attached."
    Indeed, I apologize for not checking my facts, my bad. though here is the thing right. in my E comp entry I did exactly what I said there. my doors only have a collider on, no rigid body. But my monster has a rigidbody and as such can open doors.
  • @hermantulleken in my game sometimes the enemies get close enough to the player for the origin of the shot to overlap the enemy, so they are created "inside" the enemy object's collider. The enemy object itself doesn't hurt the player. But the player's bullet shout hit the enemy...

    @CorruptedHeart oooh that's interesting I'll try sphereCast, it looks very expensive? But I guess I shouldn't care about that. Though I wonder why raycast wouldn't work where sphereCast would.

    @Pixel_Reaper I would love to use OnCollisionEnter but that would necessitate rigidbodies and I don't want to overcomplicate the physics and whatnot... Is there a way to OnCollisionEnter with moving via Translate instead of AddForce?
  • You can set your rigidbodies to be kinematic in the inspector. As far as I know, this makes them ignore physics except for the purposes of collision detection.
  • edited
    @Tuism Not 100% sure. I very rarely use translate. Though if you had a rigidbody on your objects which you just confine on its axis. you should be able to use both translate and OnCollisionEnter, without the physics math involved.

    @Elyaradine kinematic rigidbodies wont work with OnCollisionEnter. as it does not take collisions into account
  • You don't need rigid bodies for collision detection. Just colliders. Rigid bodies are for physics simulation. You can also decrease the update step size somewhere in the settings. Alternatives for bullets are: make them slower, use rays for bullet hits and just animate the bullet separately (this is how most shooters does them) or predict a few frames ahead with rays while the bullet is flying.
  • @farsicon, does that mean OnCollisionEnter works without rigidbodies? Does that mean OnCollisionEnter work with moving stuff with Translate?

    I've put up the latest web build of Jack King, there you can see the way collision detects differently from a different angle than front...

    http://makegamessa.com/discussion/1359/prototype-jack-king#Item_10

    The enemy bullet has a box collider, no rigidbody. The player object has a rigidbody, and a box collider.
    Right now when the bullet hits the player object from the front, it's a hit. That's done with a raycast (code above).
    But when the player object (it's more prominent with the vehicle) lands "on top of" the bullet it doesn't register the hit (in fact a physics collision happens... and the ship doesn't pass through the bullet)

    I can make the player collider isTrigger, but then the bullet just carries on going.

    GAH.
  • Tuism said:
    @CorruptedHeart oooh that's interesting I'll try sphereCast, it looks very expensive? But I guess I shouldn't care about that. Though I wonder why raycast wouldn't work where sphereCast would.
    It might be a little bit more expensive, I haven't really noticed. I was using Physics.Raycast for my bullet handling (in a project I am going to post soon) however it was doing odd things like shooting through walls sometimes. Switched to Physics.SphereCast and those errors disappeared.
    Thanked by 1Tuism
  • Tuism said:
    @CorruptedHeart oooh that's interesting I'll try sphereCast, it looks very expensive?
    Please unlearn that phrase until you need to re-learn it. :)

    [quote = Tuism]But I guess I shouldn't care about that.[/quote]
    Correct!
    Thanked by 2Tuism hermantulleken
  • OK I just tried SphereCast and it didn't do anything different. The biggest issue seems to be that raycasts only hits one facing face, which means... Let me illustrate:

    image

    So I suspect SphereCasts follow the same principle just with a thicker stroke - collision is still calculated on the ray at facing polygons.

    Is there a way to check whether an object is IN another collider, or...
    Oh wait... TriggerEnter... Hmmmmm, does making things isTrigger break anything about the physics?
  • @Tuism - check this out

    http://docs.unity3d.com/Documentation/ScriptReference/Collider-isTrigger.html

    sends a message instead of colliding with rigidbodies, but could be a work around using OnTriggerEnter
  • @Tuism,

    Also don't forget to cheat where possible:

    if(bullet is close enough to enemy) Explode();


    or

    if((bullet.transform.position - enemy.transform.position).magnitude < EnemyRadius) enemy.Explode();
  • @FanieG yeah that's the trigger thing I was referring to - however triggers ignore physics and my player objects use physics to fly up and down. Which means I can't just trigger everything...

    Is it a bad idea to mix objects with rigidbodies and physics with triggers and translate and etc etc...? I'm starting to feel that way...

    @hermantulleken Cool idea! That would be a great solve if all my stuff are circular/squareish...
  • Is it a bad idea to mix objects with rigidbodies and physics with triggers and translate and etc etc...? I'm starting to feel that way...
    As a general rule anything that overcomplicates your logic is a bad idea :) If it's absolutely necessary to use a bunch of different approaches to achieve your goals, then fine, but it really shouldn't be and it's just going to make things progressively more confusing as your project gains more features.
    Thanked by 2Tuism tbulford
  • edited
    @Tuism... it's a great idea even if they are not ;) For prototyping, it can get you past this hurdle and onto more important things. You may later find that your bullets have different properties only after spending a lot of time trying to fix this.

    Also, don't forget that it's all about illusion; not realism.

    Also, you can always up the precision by using more than one check...

    Don't get bogged down in the detail. (And yes, it may be an improtant detail... but you don't know until you relax constraints).
    Thanked by 1Tuism
  • Yeah I'm trying to keep it simpler rather than making it more complicated, so I can throw more features in to test and wrangle. This weekend's been blocked off for jamming (on another game, mind, but the benefits will be simultaneous) and I hope to get more updates to you guys soon :)

    Thanks again for everyone's input and support, it really means a lot to me *emotional* :P
  • So I've been trying to get this global variable thing to work and it looks so basic but it doesn't work...

    I have an empty gameObject in the scene, with this code on it:

    using UnityEngine;
    using System.Collections;
    
    public class GameSpeedControl : MonoBehaviour {
    
    public static float runningSpeed = 15;
    ...


    Omitted the rest because I *know* it does run and does not pertain to this question.

    I can't access runningSpeed from another script, when I do it tells me runningSpeed is not in this context. What am I doing wrong??? I googled and googled and everyone says it's as simple as adding static. But it's not. What is it?? @_@
  • I think you are missing this:

    float myRunningSpeed = GameSpeedControl.runningSpeed;//the GameSpeedControl is an important part
    Thanked by 1Tuism
  • OMG SO IT *IS* THAT EASY!!! THANKS!!! :D

    Then another one that's supposed to be easy...

    I have a public variable declared. A reference to a GUIText object so I can change the GUI on the fly.

    I have a prefab that's not on the scene yet... I can't drag the GUIText instance on the scene to the public variable in the editor... I can if the object was in the scene already, but I can't if it's sitting in prefab. In fact if I drag the prefab out, set the public variable, then apply and delete it, the prefab variable gets reset to None.

    How would an instantiated object make reference to something that's already in the scene? Can/should I fill that variable with something like a GetInstance or something?
  • Prefabs are reusable across multiple scenes, so you can't have one that references an object in a specific scene.

    Do you need a public variable at all? Maybe you can just use GameObject.Find?
    Thanked by 1Tuism
  • Thaaat's the one! So I can have a public variable, then when it gets instantiated, in Start, Find the specific GUI object and fill the public variable with it to use for the lifetime of the instance, right?

    Cooool :D Thanks!
  • Here's a pattern for a lazy initializing property for what you're talking about. This will keep the if checks to a minimum later on, prevent you doing unnecessary extra GameObject.Finds and just generally keep things easier to read:

    // private instance field that you'll never access directly outside of the property
    private MyComponentClass myComponent; 
    // property that you will use in your code to actually access the object
    public MyComponentClass MyComponent
    {
    	get
    	{
    		if (null == myComponent)
    		{
    			GameObject go = GameObject.Find("MyComponentsNameInScene");
    			if (null != go) myComponent = go.GetComponent<MyComponentClass>();
    		}
    		return myComponent;
    	}
    }


    And then you can use it as you would have used the field:
    if (null != MyComponent) MyComponent.DoStuff();
    Thanked by 1Tuism
  • Hey guys, so I started playing with Unity 4.3 today (the first time Im actually going to try make something in Unity). I am trying to figure out to to get if something has been clicked? In 2D Toolkit I know you can create the OnInput function and then just handle it in there. What do I need to do in 4.3?

    P.S This thread should really be a sticky :P
  • Hey guys, so I started playing with Unity 4.3 today (the first time Im actually going to try make something in Unity). I am trying to figure out to to get if something has been clicked? In 2D Toolkit I know you can create the OnInput function and then just handle it in there. What do I need to do in 4.3?

    P.S This thread should really be a sticky :P
  • Argh...sorry for the spam... :(
  • edited
    @CiNiMoD, something like this?

    bool WasClicked(GameObject Target)
    	{
    		bool output = false;
    		RaycastHit hitObject;
    
    		if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitObject))
    		{
    		        if (hitObject.collider.gameObject == Target) output = true;
    		}
    
    		return output;
    	}


    EDIT: Usage
    void Update()
    {
    	if (Input.GetMouseButtonUp(0) && WasClicked(SomeTarget)) // Left click,on top of some object
    	{
    		// Do stuff
    	}
    }
  • Because it wouldnt be Unity if it was harder than that :P Thanks :)
  • Next question (sorry, gonna be spamming this thread for a while :P). I am trying to make a progress bar. I placed a sprite over another sprite and in my script I just set the scale of my overlay sprite. Yay, it works, except that the overlay scales from the center out. How can I anchor it to the left and scale out to the right?

    Thanks :)
  • Quick fix is probably to create a parent GameObject for the overlay sprite. Offset the overlay sprite so that the parent's pivot is on the left edge of the overlay sprite. Scale the parent. :)
  • Hmmm...still new to Unity. How do I set a pivot point?
  • You don't. :) You'd effectively be using parent-child relationships as a workaround to create a fake pivot point. (i.e. your pivot becomes where the transform of your parent is situated)
  • Don't you set pivot points based on the position of an object in the gameObject? Basically where 0,0 is is the pivot point. But I've had tons of problems around that, it's not as clear-cut as it seemingly should be.
  • Ok, but this still doesnt solve the fact that its going to scale out from the middle does it?
  • edited
    If you scale the parent gameobject (the one that you're using as a fake pivot), the child objects should scale from there instead of from wherever their local pivots are.
  • edited
    So Im having the most annoying thing happen. I have 2 objects with a Box Collider 2D. One of them is my player, and the other is the ground. I have a check to see if my player is on the ground, this is the code:

    bool IsOnGround()
    	{
    		Vector3 pos = gameObject.transform.position;
    		RaycastHit2D hitObj = Physics2D.Raycast(new Vector2(0.0f, pos.y - 0.50f), - Vector2.up), 0.1f);
    		if (hitObj && hitObj.collider.gameObject.tag == "Ground")
    		{
    			return true;
    		}
    
    		return false;
    	}


    This works great for when my player hits the ground, and it returns true. The ground element is made up by taking a 25x25px sprite and scaling it to go across the bottom of the screen. The issue comes in when I duplicate the ground element and use a smaller scale. I can land on top of it, the hitObj is null :( While Im sitting on the platform if I change the scale on the x axis and make it longer IsOnGround starts to return true when my scale reaches around 13.5 ....

    I am super stumped :/

    image

    So the platform I am on doesnt return true until I make it wider?!?!
  • Your collider might not scale correctly with your ground.
  • So how do I scale my collider?
  • So how do I scale my collider?
    Choose the gameobject in the hierarchy so that it's components are shown in the inspector. The collider will be one of the components. You will be able to scale it there.
  • Is there a way to set up your scene so that you can so that you can use normal pixels as opposed to the standard way it does it (in meters I presume?)
  • Another question :P Probably a very noob one also...I have an object that gets all the items in my scene and displays their icons. It does this by calling Instantiate(SaidObject.Icon). In my Icon object I have an event listener that destroys the object when an icon was clicked. Its as simple as it sounds:

    MySystemObject.OnIconClicked += (s) => { Destroy(GameObject); };


    This works perfectly the first time I do it. When I do the process again in the same game(so, by my understanding, instantiating all the icons again) when I click on an icon, I get the following error:MissingReferenceException: The object of type 'IconBase' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.


Sign In or Register to comment.