Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Camera Controller Release

Discussion in 'Assets and Asset Store' started by Tryz, Dec 21, 2013.

  1. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    I do include a Spline Motor for following along a path.

    The path is just a spline you create with my simple spline component, but you can use the Spline Motor as a template to create the camera movement you're describing and use it with any spline tool.
     
  2. marcos

    marcos

    Joined:
    Oct 18, 2009
    Posts:
    592
    Would I be able to do this in Playmaker? (or Node Canvas, if I were to get that)

    Coding isn't within my realm of expertise.
     
  3. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    Unfortunately, no.

    When you build a custom camera motor, it has to be done in C#. The Camera Controller does a lot of work for you, but there would be coding.
     
  4. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    I figured out how to fix it not being smooth. It's as I thought, it was related to collisions. My problem was with CameraMotor.mAnchorOffsetDistance, it moves to a new value over time if it changes. I fixed this by calling CameraMotor.Initialize() after each time I set the anchor during the lerp.
     
    hopeful likes this.
  5. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    That's interesting. The code I posted was smooth even with collisions. I made sure to test that before posting it.

    I'm glad you've got it working.
     
  6. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    Hey Tim- I saw that you just added a LookAt motor to the asset-

    I'm using the Camera Controller for all my gameplay but for my "dark souls" like targeting system I switch off the Camera Controller and use a SmoothLookAt looking at a Vector3 var(calculates to find the targets upper region) and a SmoothFollow(with the look disabled) that follows the player with height, distance vars- I'm using my own sorta crappy collision system for it as well-

    I would like to do this all with your asset and not have to switch over to my custom setup- is this possible in the newest version with the motors and new LookAt motor?

    So I need it to be able to "lookAt" a Vector3 var and "follow" a GameObject var-

    Wanted to ask the master if its possible before I jump into the code- Thanks :)
     
    Last edited: Dec 31, 2016
  7. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    It can be used this way, but the "follow" part can get tricky in 3rd person.

    I build this because I wanted a "security camera" (think 1st person) that would track a target. When "Use Static Position" is not checked and an offset exists, it will work like a 3rd person camera for movement and always look at the target. The problem is that the position changes as the character rotates and it can feel clunky.

    For my "dark souls" style targeting system, I keep the same 3rd Person Follow camera that I use when not targeting. Then, when targeting, I call this function on the Camera Controller:

    mCameraController.SetTargetForward(lForward, lSpeed);

    This works well because it keeps the camera positioned using the standard 3rd person motor, but forces the camera to look in the direction I specify. This is called each frame to update the forward direction.

    Once I'm done targeting... I just stop calling the function.

    Make sure you get the latest latest version (3.10)
     
    Last edited: Dec 31, 2016
    imaginationrabbit and TeagansDad like this.
  8. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    Ah cool thanks! I got it working using two different motors just now but this way is a lot simpler- thanks Tim and yes I just upgraded to the newest version- thank you for the help.
     
    Tryz likes this.
  9. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    I have one more quick question- with the earlier version of the asset I was leveling the camera and changing the cam FOV based on the pitch using the "LocalPitch"- I can't seem to expose/find the "LocalPitch" var's I was getting/setting on an earlier version- I found the SetTargetYawPitch which I assume I can use to set the pitch- how would I get the pitch with the new version? Thx!

    Update: Opened the YawPitchMotor and found a localYaw here- will give it a try
     
    Last edited: Jan 1, 2017
  10. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    Right. Several motors inherit from YawPitchMotor. So, you can get values for LocalYaw and LocalPitch. Basically, that's the yaw and pitch relative to the anchor's forward direction.
     
    imaginationrabbit likes this.
  11. LNMRae

    LNMRae

    Joined:
    Dec 28, 2012
    Posts:
    48
    Hey, ootii, really love the asset, it's the best camera I've used and really feels AAA quality. :)

    I saw in previous conversations some discussion about using the camera with ORK framework. A few people posted code for getting the camera to track the player tag, but looks like all of it was posted prior to the big 3.0 update. I have (very) little programming experience and I'm wondering if you could point me in the direction of which script I should be looking into now in order to try implementing that behavior or looking for the player tag rather than a specific game object?

    Thanks very much!
     
  12. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    Hey @LNMRae ,

    I appreciate that. :)

    What do you mean by "track the player tag"? I think you mean mean setting the camera's Anchor property with the player's transform...

    I'm not that familiar with ORK, but I know several people do use the CC with it. I don't believe they do anything special.

    I *think* you just set the tag's transform in the Anchor property. Doesn't the "player tag" become the player at run-time?

    If not, you would create a little Monobehaviour that would run when the player is instantiated and do something like this:
    Code (CSharp):
    1. GameObject lPlayer = GameObject.FindGameObjectWithTag("Player");
    2. CameraController lCameraRig = Component.FindObjectOfType<CameraController>();
    3. lCameraRig.Anchor = lPlayer.transform;
    4.  
    When you tell this to run really depends on when ORK creates the player. Unfortunately, I won't be much help there. :(
     
  13. bmccall1

    bmccall1

    Joined:
    Jul 28, 2013
    Posts:
    120
    Is there any way to use right click to snap zoom instead of using the middlemouse scroll?

    thank you!
     
  14. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    Yes... mostly. :)

    The "Zoom Action Alias" property defaults to "Camera Zoom". In Unity's Input Manager, I tie that to the mouse wheel. If you change "Zoom Action Alias" to "Fire2", it will zoom when the right mouse button is held.

    Changing the "Smooth" property will have it snap instantly.

    Releasing the right mouse button will exit the zoom.

    It won't act like a toggle though... click to snap and click to un-snap. For that you'd have to customize the code or add a Monobehaviour that controls the camera properties based on how you want the clicking to work.
     
  15. bmccall1

    bmccall1

    Joined:
    Jul 28, 2013
    Posts:
    120
    Ah, ok. So that leads to my second question:

    I have written a wrapper for this. I pullin com.ooti.cameras.CameraController (i'm doing third person follow) and reference the "AnchorOffset". This allows me to detect right click, and override the anchor offset, but it is an instant movement, not a transition, and also, there is a value (in the gui) in CameraController, for "offset" which is a secondary offset (there is anchor offset above, and offset, in the third person follow camera parameters).

    I cannot figure out how to access the "Offset" value in the third person follow params.

    Really appreciate the help!
     
  16. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    Correct. Setting values (like "Offset") directly on the motor is setting a "hard" value. The change will be instant.

    When a transition activates, it runs two camera motors and blends the two results over time. That's where the transitioning comes from.

    Of course you can write a component to change the "Offset" over time to create any transition you want.

    In the documentation (page 15), I describe the difference between the offsets:
    http://www.ootii.com/Unity/CameraController/CCUsersGuide.pdf

    To set the offset value, you'd do something like this:
    Code (CSharp):
    1. CameraController lCameraRig = Component.FindObjectOfType<CameraController>();
    2. OrbitFollowMotor lThirdPersonMotor = lCameraRig.GetMotor<OrbitFollowMotor>();
    3. lThirdPersonMotor.Offset = Vector3.zero;
    If the motor's "Use Rig Anchor" is checked, it will use the Anchor and Anchor Offset set on the Camera Controller itself. However, by unchecking "Use Rig Anchor", you can specify an Anchor and Anchor Offset specific to that motor and those specific values will be used instead.

    Code (CSharp):
    1. lThirdPersonMotor.Anchor = gameObject.transform;
    2. lThirdPersonMotor.AnchorOffset = Vector3.zero;
    I hope that all makes sense. :)
     
  17. bmccall1

    bmccall1

    Joined:
    Jul 28, 2013
    Posts:
    120
    Yeah that is great. thank you very much!
     
    Tryz likes this.
  18. LNMRae

    LNMRae

    Joined:
    Dec 28, 2012
    Posts:
    48
    ORK Framework has the player spawning at runtime, so I've had trouble getting the camera rig to follow the player gameobject because it doesn't recognize the clone ORK generates (which makes sense), but the little bit of code you posted looks like exactly what I had in mind with it searching for the tag rather than the gameobject. I'll give this a try when I next have the time to experiment. Thank you so much for giving such a detailed response.
     
    Tryz likes this.
  19. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    Tryz likes this.
  20. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    You so rock!! I'll link to it from the Vault as well.

    If there's an ootii asset you want, let me know and I'll send a voucher. :)
     
    imaginationrabbit likes this.
  21. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    I think I already own all you're assets :) No problem Tim- you've given me tons of free tech support since I bought your stuff, so no problem at all. I'm a beginning programmer so making actions is fun practice- if you need Playmaker actions for your other assets let me know-
     
    TeagansDad and Tryz like this.
  22. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    hahaha... We'll, I appreciate that.

    The Motion Controller could use them. There's only a couple of key functions ActivateMotion, DeactivateMotion, SetTargetPosition, etc. If you find time to got after the MC, I'd really appreciate it.

    The Spell Casting Motion Pack is yours once I'm done with it. :)
     
    imaginationrabbit likes this.
  23. Kaneleka

    Kaneleka

    Joined:
    Sep 23, 2013
    Posts:
    18
    @Tryz I ran into a rather obscure bug while troubleshooting collisions with your camera controller. More specifically the bug I think is actually in the code you borrowed from http://answers.unity3d.com/questions/60959/mask-field-in-the-editor.html?page=1&pageSize=5&sort=votes
    In my own layer setup I'll get values similar to the following -- see watch window below.
    CameraControllerEditor.cs
    upload_2017-1-23_14-16-20.png

    If I replace this static method LayerMaskField in EditorHelper.cs with what was posted on page2 from the link above everything is fine.
    Code (CSharp):
    1. public static int LayerMaskField(GUIContent rGUIContent, int rMask, params GUILayoutOption[] rOptions)
    2.         {
    3.             LayerMask[] layers = new LayerMask[32];
    4.             int m = 0;
    5.  
    6.             for (int i = 0; i < 32; i++)
    7.             {
    8.                 int layerID = i;
    9.                 string name = LayerMask.LayerToName(layerID);
    10.                 if (name != null && name.Length > 0)
    11.                 {
    12.                     layers[m] = layerID;
    13.                     m++;
    14.                 }
    15.             }
    16.  
    17.             string[] names = new string[m];
    18.             for (int i = 0; i < m; i++)
    19.             {
    20.                 names[i] = LayerMask.LayerToName(layers[i]);
    21.             }
    22.  
    23.             LayerMask result = EditorGUILayout.MaskField(rMask, names);
    24.  
    25.             return result;
    26.         }
    As this is in your framework I'm surprised this hasn't come up earlier...
     
    Tryz likes this.
  24. jason-fisher

    jason-fisher

    Joined:
    Mar 19, 2014
    Posts:
    133
    Will this work with a spherical planet/gravity? i.e. follow the orientation of the target for 'up'?
     
  25. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    Yes, most motors do.

    I have a test scene where the character walks upside down and the camera keeps the orientation in relation to the character. There shouldn't be an issue.
     
  26. Kiwi-Hawk

    Kiwi-Hawk

    Joined:
    Jul 17, 2015
    Posts:
    288
    Kia ora

    You will maybe not remember me, we spoke via email a long time ago, I walked away because it all seemed so far over my head and programming is not something at my age I want to try to remember, anyway, back having another shot at it seeing the tools have progressed heaps, I never forgot your kindness Sir I just brought this and I'm hoping with the way this is setup I can get to a place where I can get the type of controller used in the Elder Scrolls series where we have a third person camera that can (via a toggle(F key)) switch to first person. This is great for when one enters a room or confined space
     
    Tryz likes this.
  27. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    I figured out what's going on...

    The approach I'm using is actually fine. Having a negative value like that is totally cool with a mask.

    However, my raycast functions have logic that don't like values less than 0. So, with a value like what you show (-1073733632)... I force a collision and shouldn't.

    It affects all my collisions. However, it really only occurs as people start using layer 29+. I think the reason no one (including me) has hit this is that we just haven't used that many layers for collisions.

    Thanks for raising this up! I'll work on a fix and get it rolled out.
     
  28. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    Hi! I couldn't forget "Kia ora" ;)

    With the new transitions, you can certainly have the camera pull and and out based on the key press. You'll want to set the entry up in Unity's Input Manager and then, you can use the name of the entry in the transition motor's "Action Alias" field.

    Check out page 22 of the User's Guide:
    http://www.ootii.com/Unity/CameraController/CCUsersGuide.pdf

    That takes you through something close. If you get stuck or need help, feel free to post or email. :)
     
  29. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    Do you have a setup for inControl, or do I need to implement that myself?
     
  30. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    Not one for InControl.

    I've got an input source for Rewired, Easy Touch 5, Easy Input, and Unity's Input Manager. You can get the first two off the Vault: www.ootii.com/UnityMotionVault.cshtml

    I have a video that talks about creating input sources.


    You're really just creating a wrapper for your input solution. Unfortunately, there's a lot of them to keep up with. :)

    If you run into any issues, feel free to email tim@ootii.com and I'll help how I can. I just don't own InControl.
     
  31. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    Thanks, got it working now, but I had another question. Is there a way to set a default angle on a camera motor?
     
  32. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    Good stuff.

    The camera will default to how its setup in the scene, but move closer to respect the distance property.

    So, while there's not default angle. If you position the camera in the scene how you want it to start, the first active camera motor will respect it.

    I hope that makes sense.
     
  33. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    I had some people ask how to setup the Camera Controller with the Motion Controller.

    This video will show you how we can do that in about a minute:
     
    ayk likes this.
  34. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    That makes sense, but if I don't want to use the default angle? I want to zoom my camera out and change the default angle.
     
  35. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    You can use the SetTargetYawPitch() function on the CameraController.

    /// <summary>
    /// Causes us to ignore user input and force the camera to the specified localangles
    /// </summary>
    /// <param name="rYaw">Target local yaw</param>
    /// <param name="rPitch">Target local pitch</param>
    /// <param name="rSpeed">Degrees per second we'll rotate. A value of -1 uses the current yaw speed.</param>
    /// <param name="rAutoClearTarget">Determines if we'll clear the target once we reach it.</param>
    CameraController.SetTargetYawPitch(45f, 0f, 0f, true);
     
  36. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    Oh that will work great thanks!

    Is there a way to have a transition motor work from any camera state? Similar to how unity animation states work. Or do I need to add a transition from each possible camera state to any camera state they may go to?
     
  37. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    At least for now, it has to be specific.

    I didn't think about supporting "current state". I'll add that to my to-do list... I'm just not sure when I'll get to it.
     
  38. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    Thanks for the quick response times! It's helping me replace our old camera quickly, yours is soooo much easier to work with.

    I've noticed that my ViewX and ViewY overrides work and I can see them working in visual studio, however the MovementX and MovementY don't seem to be functioning the same way. When I inspect them in visual studio they're never getting hit. So it appears I don't have the camera system functioning properly and I'm lacking a way to override the movement control when a different behavior is desired. What might I be missing?

    Code (csharp):
    1.  
    2.         /// <summary>
    3.         /// Retrieves horizontal movement from the the input
    4.         /// </summary>
    5.         public override float MovementX
    6.         {
    7.             get
    8.             {
    9.                 if (!_IsEnabled) { return 0f; }
    10.  
    11.                 return PlayerActions.Move.X;
    12.             }
    13.         }
    14.  
     
  39. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    You're overriding them correctly. I don't believe the CC uses them though. The CC primarily uses the ViewX and ViewY while a character controller to move the character would use MovementX and MovementY.

    What are you trying to do with them?
     
  40. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    I'm trying to turn off the roll of the camera when my character tilts on a motorcycle. But I'm not using your character controller
     
  41. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    There's no property for that, but you could do a couple of things:

    1. Have the motorcycle be a child of higher level object. This way you would move the higher level transform, but tilt the lower level model. That's what I do in the swimming motion so the player can tilt. What's nice is that it keeps your main transform always up and facing in the movement direction even if you're doing a wheelie, tilting, etc.

    2. Have an "anchor" transform that is a child of the motorcycle, but add a component so it counters the roll. Then, have the camera use that as the anchor.

    3. You could copy the motor you're using and customize it. Then, add the counter-roll logic directly in your new camera motor. I don't talk a lot about this, but the CC is built to be expanded on. So, you can create new camera motors and still take advantage of my collision detection, zooming, fading, transitions, etc.

    I think #1 would probably be the easiest.
     
  42. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    Ok putting it as a child and killing the rotations works good but now I'm wondering how when I change cameras using the transition motor to specify the camera's location. ie I have camera at some rotation around my bike and I want the camera to rotate to behind the player when I switch to my bike camera.
     
  43. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    You have to get creative with the motors. Here's what I did:

    1. Created a scene with the character and a "bike". The character stood next to the bike.

    2. Added 4 motors to the CC
    - 3rd Person Follow for the character
    - 3rd Person Follow for the bike
    - 3rd Person Follow for the transition to the bike (this is not a transition)
    - Transition to go from character to bike

    The first motor is just the standard character motor.

    The second motor is the "standard character" motor, but the character is the bike. So, we uncheck "Use Rig Anchor" and set the Anchor (bike) and Anchor Offset there.

    The third motor is a bit of a trick. Set it up exactly like the second motor. But, set the Yaw Range to (0, 0). So, this motor forces the camera behind the bike.

    The transition motors is setup with the following:
    - Start Index = 0
    - End Index = 2 (this is our bike motor that doesn't allow rotation)
    - End Index Override = 1

    When the transition starts, it will blend the character motor and the third motor. This will cause the camera to move behind the bike. However, the player can't rotate it as it will be fixed with a yaw range of (0, 0).

    When the transition finishes, the End Index Override will trigger and the second motor (the real one for the bike) will become active.

    I tested it real quick and it works. I'm sure there's some clean up you can do. If you wanted, you could use the spline motor to create nice transitions, etc. But, this should give you a starting point.
     
  44. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    Thanks for the tip, this method is working out pretty well. If I wanted to add a number to the camera motors in the displayed list of camera motors where would that label be? Hard to know which camera is which by number when the count is getting up there.
     
  45. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    I'm also having an issue where the camera is flipping around when I use a negative Z offset with my anchor transform which is only rotating on the y axis.
     
  46. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    You'd have to modify that in the CameraControllerEditor.cs file. There's a function called DrawMotorListItem. That's where we'd do it.

    I'll add that to the list.
     
  47. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    I'll Check that out tomorrow.
     
  48. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    397
    Changing
    EditorGUI.LabelField(lTypeRect, (lMotor != null ? GetFriendlyName(lMotor.GetType()) : "null"));
    to
    EditorGUI.LabelField(lTypeRect, (lMotor != null ? rIndex + " " + GetFriendlyName(lMotor.GetType()) : "null"));
    is what I did, looks ok.
     
    Tryz likes this.
  49. Tryz

    Tryz

    Joined:
    Apr 22, 2013
    Posts:
    3,402
    I added similar logic to the editor. It will be there for the next update.

    I'm not seeing an issue.

    Here's what my setup looks like:


    Can you email me some pictures of your camera settings? That may help me duplicated what you're seeing.
     
  50. Obsurveyor

    Obsurveyor

    Joined:
    Nov 22, 2012
    Posts:
    277
    I'm having some trouble with the Targeting In/Out camera motors. I'm using a custom input source using InControl and I have it mapped to the right trigger. It doesn't always seem to react to pressing the trigger to target right away. Some times it's instant like it should be, other times you hold it down and nothing happens for a second or sometimes even multiple seconds.

    The weird thing is that I can see the checkbox for Targeting In Active get checked immediately on press, even if the camera doesn't start moving for a second or more. The documentation says that only one motor can be active at a time and when I press the trigger the only one active is Targeting In.