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

Skier character controller script and skiing physics need serious help please

Discussion in 'Scripting' started by kootenay, Feb 17, 2011.

  1. kootenay

    kootenay

    Joined:
    Feb 8, 2011
    Posts:
    116
    OK, just getting into scripting a little more (limited javascript knowledge), but having fun making a skiing demo on a mesh imported from Google Earth. You can play with my total hack below... I'd love help on actual script changes (sorry, I need things really spelled out) for my Character Controller script which I've included further below;

    - how do I make the "up" arrow key forward (vs reverse)?
    - how do I stop the trail renderer when skier is airborne?
    - how would I make the jump (space bar) perpendicular to the slope, vs straight up all the time
    - any ideas about making the snow particle renderer only active during turns?

    Sorry for all the questions, but I figure this script and solutions would help others also doing ski/snowboard games.

    Play rough demo here;
    http://charlwood.com/ymir/ymir/WebPlayer/WebPlayer.html

    MoveAround.js script;

    var speed : float = 6.0;
    var jumpSpeed : float = 8.0;
    var gravity : float = 10.0;

    private var moveDirection : Vector3 = Vector3.zero;

    var tracker: Transform;
    var rotateSpeed = 3.0;
    function Update ()
    {
    var controller : CharacterController = GetComponent(CharacterController);
    transform.Rotate(0, Input.GetAxis ("Horizontal") * rotateSpeed, 0);
    var forward = transform.TransformDirection(Vector3.forward);
    var curSpeed = speed * Input.GetAxis ("Vertical");
    controller.SimpleMove(forward * curSpeed);

    var hit1: RaycastHit;
    var hit2: RaycastHit;

    if (Physics.Raycast(tracker.position, -Vector3.up, hit1)) {
    if (Physics.Raycast(tracker.TransformPoint(Vector3.forward * 0.1), -Vector3.up, hit2)) {
    transform.rotation = Quaternion.LookRotation(hit2.point - hit1.point, hit1.normal);
    }

    if (controller.isGrounded) {
    // We are grounded, so recalculate
    // move direction directly from axes

    //GetComponent(TrailRenderer).enabled = true;
    moveDirection = Vector3(Input.GetAxis("Horizontal"), 0,
    Input.GetAxis("Vertical"));
    moveDirection = transform.TransformDirection(moveDirection);
    moveDirection *= speed;

    if (Input.GetButton ("Jump")) {
    moveDirection.y = jumpSpeed;
    }

    }
    }
    // Move the controller
    controller.Move(moveDirection * Time.deltaTime);
    }
    function FixedUpdate () {
    rigidbody.AddForce (-Vector3.up * 10);
    }
    @script RequireComponent(CharacterController)
     
  2. adularia25

    adularia25

    Joined:
    Feb 14, 2011
    Posts:
    30
    Models in Unity move on the 'z' access, so it is best if the 3D model you are using is created with the blue 'z' arrow pointing forward. Chances are your character was modeled backwards, which would explain why all the 'forward' commands go in reverse. To fix the problem in the code, simple change all the Vector3.forward to -Vector3.forward (or Vector3.back). Otherwise, you can rotate the model 180 degrees and reimport it.

    As for the trail renderer, you will need a boolean value to check whether the character is grounded or not and an if statement such as:

    Code (csharp):
    1.  
    2. if(isGrounded == true){
    3. GetComponent(TrailRenderer).enabled = true;
    4. }else{
    5. GetComponent(TrailRenderer).enabled = false;
    6. }
    7.  
    To fix the jump, you would want a raycast coming down from the center of the character, then caculate your jump based on the opposite direction of that raycast. Sadly, I'm not much good with raycasts, but the locomotion tutorial might show you how to figure it out:

    http://unity3d.com/support/resources/unity-extensions/locomotion-ik

    Finally, as with the trail renderer, you will have to creat a boolean value to show whether the player is turning or not. Then a simple if statement to see if the particles should be activated or not.

    I hope this helps.
     
  3. frederiksen

    frederiksen

    Joined:
    Sep 28, 2010
    Posts:
    16
    you just raycast down, the hit information gives you the normal of the thing you hit as if by magic. But make sure that you ignore the player.

    But for the skiing guy himself i wouldn't use the character controller. Let the physics do the work for you. So either i'd use two boxes that look like skiier to which you could add a box(the guy standing on the skiies) and connect them with constraints, than you addtorque or some force to do the turning. Or you could think of the skis as a car and look for car tutorials. I don't know if either of that methods really is that good but i think in the long haul something like that will be easier than the character controller.
     
  4. kootenay

    kootenay

    Joined:
    Feb 8, 2011
    Posts:
    116
    Adularia - this is great stuff. You remind me of why this forum is so great, I really appreciate the detailed response. Well - good call on reimporting the 3d skier, that worked. Tried the code you supplied for the trail renderer - works great to remove the trail when the skier jumps, but unforuntately, it removes all of the previous trail, and then re adds them all when on the ground again. Mmm... maybe a line vs trail renderer would work, or a raycast line drawing code bit or something... any input here would help.

    Re jumping, ok, will look more into raycasts, thanks for that direction as well! :) Yes, VERY helpful!
     
  5. kootenay

    kootenay

    Joined:
    Feb 8, 2011
    Posts:
    116
    Interesting comments re using the car tutorials vs the character controller - I never thought of that, so great idea to investigate, thank you so much for that. :)
     
  6. kootenay

    kootenay

    Joined:
    Feb 8, 2011
    Posts:
    116
    OK, well I'm getting closer with this skier character controller script below I think - though my line is raycasting down from above, and under skier, but only appears below the skier when he's in the air. It also doesn't remain behind him... any specific script changes/help would be mucho appreciated. I'm at my wit's end now testing various things, and I think my understanding of raycasts and lines is a bit foggy.

    var speed : float = 6.0;
    var jumpSpeed : float = 8.0;
    var gravity : float = 10.0;
    var line : LineRenderer;

    private var moveDirection : Vector3 = Vector3.zero;

    var tracker: Transform;
    var rotateSpeed = 3.0;
    function Update ()
    {

    var controller : CharacterController = GetComponent(CharacterController);
    transform.Rotate(0, Input.GetAxis ("Horizontal") * rotateSpeed, 0);
    var forward = transform.TransformDirection(Vector3.forward);
    var curSpeed = speed * Input.GetAxis ("Vertical");
    controller.SimpleMove(forward * curSpeed);

    var hit1: RaycastHit;
    var hit2: RaycastHit;

    if (Physics.Raycast(tracker.position, -Vector3.up, hit1)) {
    if (Physics.Raycast(tracker.TransformPoint(Vector3.forward * 0.1), -Vector3.up, hit2)) {
    transform.rotation = Quaternion.LookRotation(hit2.point - hit1.point, hit1.normal);
    line.SetPosition(0, hit1.point);
    line.SetPosition(1, hit2.point);
    }

    if (controller.isGrounded) {
    // Make a trail
    var hit : RaycastHit;
    var ray = new Ray (transform.position, -Vector3.up);
    line.SetPosition(2, ray.origin);
    if (Physics.Raycast (ray, hit, 100)) {
    line.SetPosition(3, hit.point);
    } else {
    line.SetPosition(3, ray.GetPoint(100));
    }

    // end
    moveDirection = Vector3(Input.GetAxis("Horizontal"), 0,
    Input.GetAxis("Vertical"));
    moveDirection = transform.TransformDirection(moveDirection);
    moveDirection *= speed;

    if (Input.GetButton ("Jump")) {
    moveDirection.y = jumpSpeed;
    }

    }
    }
    // Move the controller
    controller.Move(moveDirection * Time.deltaTime);
    }
    function FixedUpdate () {
    rigidbody.AddForce (-Vector3.up * 10);
    }
    @script RequireComponent(CharacterController)
     
  7. kootenay

    kootenay

    Joined:
    Feb 8, 2011
    Posts:
    116
    Anyone have any ideas on this skier script? Anyone, anyone... Beuller, Beuller... :)
     
  8. Plasticlay

    Plasticlay

    Joined:
    May 6, 2016
    Posts:
    16
    Hey dose your ski asset work with 2018 and can it work with key board/ controller?
     
  9. unity_C31BF402450438D818F7

    unity_C31BF402450438D818F7

    Joined:
    Jun 24, 2021
    Posts:
    1
    dude just get and asset its not that hard
     
  10. Plasticlay

    Plasticlay

    Joined:
    May 6, 2016
    Posts:
    16