Search Unity

Contextual interaction script

Discussion in 'Scripting' started by Obscurity, Dec 7, 2007.

  1. Obscurity

    Obscurity

    Joined:
    Nov 13, 2007
    Posts:
    203
    Hello,

    I'm working on an environment in which I'd like to have contextual interaction with objects. By this I mean for example if you click on a door it rotates a specific amount or if you click on a coffee mug it gets picked up gravity gun style, etc. I plan to do this with one script under the FPS controller. I don't really need much help with the individualized interaction parts (yet), just with the initial if/then logic setup.

    My initial thought was to try and do it based on naming convention. If an object had "pancake" in the name then flip it. Something like that. Of course an engineer friend laughed at the painful inefficiency of doing a string search like that with every click and instead recommended that I assign each object type an integer and use a compare/switch type statement.

    Related to this, does Unity allow you to do an ordered list where you basically have a predefined list of readable names that correspond to integers? Something like
    list ent_types = { pine, grass, rock} where those things get auto-assigned numbers and you don't have to track what values they have. You just do

    if my.ent_type == rock then
    tree = false
    end if

    Anyone have any thoughts on how to do something like that? Maybe using GetInstanceID? Any pointers or ideas would be appreciated.

    Thanks


    PS- Just a few more days until I purchase my license! I can't believe what I've been able to do with just the demo in such a short span of time.
     
  2. pete

    pete

    Joined:
    Jul 21, 2005
    Posts:
    1,647
    if you just want to know if it's a rock or a tree you could use tags. to get more complex you might consider a finite state machine type set up. you could set up a controller script ie:

    var weight = 1.0;
    var flipable = 1.0;
    var rotate = 1.0;

    then set those variables on each object and use them to decide how much force it takes to react ie:

    rotate = 0.0 means it won't rotate
    rotate = 0.5 means it will but takes a bit
    rotate = 1.0 means it will easily rotate

    function flip(){
    flipable = Input.GetAxis("Horizontal") * Time.deltaTime;
    if (flipable > 0.2){
    ...flip it
    }
     
  3. Obscurity

    Obscurity

    Joined:
    Nov 13, 2007
    Posts:
    203
    Thanks for the tips, Pete. I think I'll start with using tags for now. I appreciate the FSM advice though. I'll probably use something like that down the road.
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Most programmers' advice needs to be taken with a grain of salt (ours included!) The engineer who laughed at your based-on-name idea was (IMO) wrong, probably used to coding things that loops hundreds or thousands of times and therefore accustomed to high efficiency. When you're talking about something that happens ONCE when a user clicks, efficiency is no object - you can have an incredibly slow algorithm and it will still be just fine. What takes far more precedence are things like flexibility and code readability, which the "based on name" approach has in spades.

    Any number or type based approach will require you to attach components to your interactive objects. This is not a bad thing, but it is definitely more annoying than simply typing "-pickup" at the end of the name, and centrally locating your functionality as opposed to spreading it over dozens of tiny script files means fewer places to make mistakes and debug. On the other hand, using the component approach would give you more flexibility... so really it's just your own preferences.

    If you do want to take the numbered approach, you can use an enum and get a dropdown list in the inspector.

    Code (csharp):
    1.  
    2. //in InteractiveObject.js
    3. enum InteraciveObjectType {Pickup, Pancake, Door}
    4. var type : InteractiveObjectType;
    5.  
    6. //in your controller object
    7. if (thisObject.GetComponent(InteractiveObject).type == InteractiveObjectType.Door) {
    8. //door code
    9. }
    10.  
    11.  
    (Note that if you have many objects that do calculations in FixedUpdate, a string-based search would be so slow that it would indeed be a bad idea. But one click, the difference will be measured in milliseconds not FPS.)
     
  5. Obscurity

    Obscurity

    Joined:
    Nov 13, 2007
    Posts:
    203
    Cool. Thanks, StarManta. I feel slightly vindicated now. I was indeed trying to keep it simple for debugging. Appreciate the code sample for the enum approach too.