Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

need help on creating cube sphere cylinder scene for study

Discussion in 'Getting Started' started by kbr0n, Aug 28, 2016.

  1. kbr0n

    kbr0n

    Joined:
    Aug 28, 2016
    Posts:
    24
    hello world!

    I'm an art student who also teaches art classes for kids and I'm looking for a way to show how light behaves on the basic geometric forms, for shading practices. For my suprise I could not find an application that would do 'only' that. This example is exactly what I'm looking for, but it does not require all these controls, just the ability to move the camera around the object (sphere, cube, cylinder) and change the light angle.

    http://www.vfxscan.co.uk/anatomy360/unity/WebPlayer.html

    Is it too hard to do this? I´m n00b on Unity but I like to learn.

    any ideas on how to get started?

    I created the objects, the light source
    but how can I make this interactive?
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    What you're describing is pretty easy for a programmer, but won't necessarily be easy for a non-programmer.

    It's like those "learn to draw" books with illustrations like this:


    ...but when most of us (non-artists) try it, the best we can do looks something like this:



    So, there's skill and learning involved, is what I'm saying. :) But, all that said, we can probably talk you through it.

    The first step is defining exactly how you want your app to behave. How should the user move the camera around the object? Grab anywhere & drag? Manipulate a slider or two? Use the keyboard? What are the limits on its motion (can it turn upside down, for example)?

    And when you say "change the light angle," how exactly should that be done? Do you want to have several different lights at different angles, which they can turn on and off with simple switches? Or do they need to be able to drag the lights around arbitrarily, too?

    UI (user interface) elements in Unity are pretty darn easy, so probably the easiest avenue for you would be to use these (sliders, buttons, switches) to control your scene. So, if you can think of a way to do that that would be satisfactory, go with it.

    Let us know when you've got that figured out, and we'll try to help!
     
    kbr0n likes this.
  3. kbr0n

    kbr0n

    Joined:
    Aug 28, 2016
    Posts:
    24
    hi, thank you for your reply

    regarding your questions:

    How should the user move the camera around the object? Grab anywhere & drag?
    like I said, exactly like this example would be ideal: http://www.vfxscan.co.uk/anatomy360/unity/WebPlayer.html

    Controls


    Rotate Camera :: Left Click + Alt (kinda like orbital view, I guess. the object never moves, only the camera around it)

    Pan Camera :: Space + left click

    | Zoom Camera :: Shift + drag up / shift + drag down

    | Rotate Key Light:: Right Click


    And when you say "change the light angle," how exactly should that be done? Do you want to have several different lights at different angles, which they can turn on and off with simple switches? Or do they need to be able to drag the lights around arbitrarily, too?


    -> it´s easier to look at the example than try to put it into words, but I think it's just one directional or spot light, coming from above, and you can rotate it around the object. It would be nice to have more, like rim light or fill light, but one would be a nice start.

    I´m guessing I need to add a component, something like a event trigger to the light, but I still don't know how to do it.

    (I can do a little coding, javascript and html, tho.)
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    OK, thanks for summarizing... I did try to run the example, but it wouldn't come up for me. (I see it's working now, though... go figure.)

    Right! So, this is not the easy path. It's going to involve a bit of math. But we can do it.

    Let's start by breaking the problem into two scripts: one to rotate the camera, and another to rotate the light. Let's put the light one aside for now, and only worry about the camera.

    To manage the camera, you're going to use a bit of a trick. Create an empty game object in your scene, and call it Camera Holder. Position this exactly at the origin of your model, that is, at where you want the camera to always be looking. Now put the camera inside this object in the hierarchy. Set the camera's position (which is relative to the Camera Holder) to 0, 0, 10, and looking in the -10 direction, so it's looking straight at the model.

    Now notice that when you (manually) rotate Camera Holder, the camera rotates around the model, but always looks at it. Neat, huh? Now we just need a script to do that for you at runtime.

    Create a new C# script, and call it something like CamMove. Double-click it, and it should open in a code editor.

    Now, the basic idea here is: you'll have a couple of properties that define where the camera is, in terms of its angle around the Y axis (e.g. 0 to 360 degrees), and its elevation (probably -30 to 90 degrees or so — unlike the example, I recommend you limit this to a reasonable range). In the Update event, you will see if the right combination of buttons are down to mean you should be moving the camera, and if so, you'll adjust these two properties accordingly, and then compute a new position for the camera.

    So, something like this:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class CamMove : MonoBehaviour {
    4.     public float yAngle = 0;
    5.     public float elevation = 30;
    6.  
    7.     void Update() {
    8.         // To-Do: check buttons, and update yAngle and elevation according
    9.         // to Input.GetAxis("Mouse X") and Input.GetAxis("Mouse Y")
    10.        
    11.         // Then, update the camera position.
    12.         // (This assumes the camera is a child of this transform, positioned
    13.         // some distance away from the origin, at which it is pointed.)
    14.         transform.rotation = Quaternion.Euler(elevation, yAngle, 0);
    15.     }
    16.  
    17. }
    Attach this script to Camera Holder (not to the camera itself). Run, and fiddle with those yAngle and elevation properties. You should see the camera rotate around the subject.

    Let me know how you get on with all that, and we'll take the next step. (Or if you want to try to apply the Input.GetAxis calls to update yAngle and elevation, please do! Post what you come up with and we'll have a look.)
     
    kbr0n likes this.
  5. kbr0n

    kbr0n

    Joined:
    Aug 28, 2016
    Posts:
    24
    thank you so much!
    gonna try that and let you know how it turned out


    -------

    ok! I manage to get things done until the "To-do" part

    the parenting thing was really handy for this, right on

    I think I understand what needs to be done but I need to study some more scripting

    Input.GetAxis is a method/function? I need to know these names! back to research!
    thank you once again
     
    Last edited: Aug 29, 2016
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Yes, that's the GetAxis method of the Input module. The axis name you provide must match one of the axes defined in the Input Manager tab (which you get to via Edit > Project Settings > Input). There are a whole bunch of standard, predefined axes, including "Mouse X" (which is how much the mouse has moved horizontally) and "Mouse Y" (same but vertically). So, unless you've messed with them, you already have those axes set up.

    So, though I haven't actually tried it, the To-Do part should look something like this:

    Code (CSharp):
    1.         yAngle = yAngle + Input.GetAxis("Mouse X") * 60;
    2.         elevation = elevation + Input.GetAxis("Mouse Y") * 60;
    3.         elevation = Mathf.Clamp(elevation, -30, 90);
    4.  
    Those "* 60" bits multiply the mouse movements by 60 degrees, which is a number I just pulled out of thin air. It's probably too fast or slow; you can tweak it until the motion feels right to you. (If you really want to get fancy, you could add public properties for these — perhaps "yAngleSpeed" and "elevationSpeed" — and use those instead of the numbers here, which would allow you to tweak the speed while running. But that's not necessary.)

    The last line just limits the elevation to a reasonable range, since if you allowed elevation changes to actually turn the camera upside down, then we'd need to detect when that's the case and reverse the yAngle changes... it gets a little complicated. Better to just clamp the elevation value to a sensible range. You may want to adjust exactly what those limits are.
     
    kbr0n likes this.
  7. kbr0n

    kbr0n

    Joined:
    Aug 28, 2016
    Posts:
    24
    I really appreciate your help, thank you

    here's how the whole script code goes:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class camera-sumpimpa : MonoBehaviour
    5. {
    6.   public float yAngle = 0;
    7.   public float elevation = 30;
    8.  
    9.   void Update()
    10.   {
    11.   yAngle = yAngle + Input.GetAxis("Mouse X") * 60;
    12.   elevation = elevation + Input.GetAxis("Mouse Y") * 60;
    13.   elevation = Mathf.Clamp(elevation, -30, 90);
    14.   transform.rotation = Quaternion.Euler(elevation, yAngle, 0);
    15.   }
    16.  
    17. }
    18.  
    but it's returning a parsing error
    Assets/camera-supimpa.cs(3,20): error CS8025: Parsing error
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    OK, that "(3, 20)" means the error was detected on line 3 of the script, column 20. You got an extra blank line in there when you pasted the code, so line 3 is really this one:

    Code (csharp):
    1. public class camera-sumpimpa : MonoBehaviour
    And if you count over, character 20 is the "-" in camera-sumpimpa. And "Parsing error" is computer-speak for "Wtf?!?".

    So, it's telling you that you can't have a "-" in a class name. Just take it out and you'll be fine. (But also, note that the name of the class here must match the file name, except without the ".cs" at the end. So you may need to rename the file too.)
     
    kbr0n likes this.
  9. kbr0n

    kbr0n

    Joined:
    Aug 28, 2016
    Posts:
    24
    wow!! it worked!

    thank you so much!

    right now, as soon as the mouse moves the camera position also moves, I mean, there's no need to left click for it to work

    If I wanted to add that 'wait for the click' behaviour, this would be the line to change?

    Code (csharp):
    1.  
    2. yAngle = yAngle + Input.GetAxis("Mouse X") * 10;
    3.  
    something like 'OnMouseClick' as a condition maybe?
     
  10. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Yes, kind of. You need to put the entire guts of the Update method inside an if block. So it'd look like this:

    Code (CSharp):
    1. void Update() {
    2.    if (Input.GetMouseButton(0)) {
    3.       // ...do the stuff you're doing now...
    4.    }
    5. }
    Let me know if that makes sense (and if you need to add more conditions, like also holding the Alt key, though I don't see why you should).
     
    kbr0n likes this.
  11. kbr0n

    kbr0n

    Joined:
    Aug 28, 2016
    Posts:
    24
    worked like a charm!

    I´ll try to do a similar thing for the light now, thank you
     
  12. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Yep! Light control should be almost the same — put it inside an empty Light Holder game object, and give it a very similar script, except that you'll want to check Input.GetMouseButton(1) (for the right mouse button), or use Input.GetKey to check for some modifier key.

    I'm afraid I probably won't be much help for the next few days... going in for knee surgery tomorrow. Fun fun!
     
    kbr0n likes this.
  13. kbr0n

    kbr0n

    Joined:
    Aug 28, 2016
    Posts:
    24
    you´ll be on my prayers, brother!

    thank you and good luck!