Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Sylux102 · Mar 04, 2015 at 05:16 PM · rotationraycastingalignmenthovercraft

How to steer a hovercraft that aligns itself to a surface normal?

How can I do this? I've created a hover car, and I can move it around and that's cool. But if I move it over any sort of slope it will work until the center of the car is past the peak of the slope. Then the car flies into infinity or falls really slowly. I'm casting a ray from the car's transform straight down, and I'd like to know how to get the angle of the ground and match it on my hover car. Kind of like a magnetic system but it doesn't have to go upside down or on walls or anything. Basically I'm trying to achieve a Halo Ghost or Destiny Sparrow kind of a vehicle. It can flip over with normal physics but it floats. I can't use wheelcolliders with no mesh because the vehicle must also strafe. This is very perplexing and I can't seem to figure it out. Help is much appreciated.

I'm using AndyMane84's hover car script (I think that's the name iirc) but slightly modified. Here's the modified script.

  var driveForce: float;
  var hoverHeight: float;
  var thrustForce: float;
  var steerForce: float;
  var steerPosZ: float;
  var thrusters: Vector3[];
  var maxVelocity: float;
  var layerMask: LayerMask;
  var enableControl: boolean = false;
  static var driveMulti: float =1;
  static var steerMulti: float =-1;
  var steer: float;
  var targetNormal : Vector3;
  var hoverHit: RaycastHit;
  var boostMultiplier : float;
  var force : float:
  var offHeight : float;
  var mainBooster : GameObject;
  var speedBooster : GameObject;
  var mainCamera : GameObject;
  private var motBlur : MotionBlur;
  var target : Transform;


  function Start ()
  {
       mainBooster.SetActive(true);
       enableControl = true;
       speedBooster.SetActive(false);
       motBlur = mainCamera.GetComponent(MotionBlur);
  
  }
  
  function Update ()
  {
       var dwn  = transform.TransformDirection (Vector3.down);
       if(Physics.Raycast(transform.position, dwn, hoverHit))
       {
            if(hoverHit.distance >= offHeight)
            {
                 enableControl = false;
                 rigidbody.drag = 0.0;
            }
            else
            {
                 enableControl = true;
                 rigidbody.drag = 1.5;
            }
       }

       if(Input.GetButton("Fire2"))
       {
            force = (driveForce * boostMultiplier);
            mainBooster.SetActive (false);
            speedBooster.SetActive (true);
            motBlur.enabled = true;
       }
       else
       {
            force = driveForce;
            mainBooster.SetActive (true);
            speedBooster.SetActive (false);
            motBlur.enabled = false;
       }
  }

  function FixedUpdate () {
      var hit: RaycastHit;
      var normalhit :RaycastHit;
      var addedhit :RaycastHit;
      var addedforce : float;
      
      
      if (Physics.Raycast(transform.position, -transform.up, normalhit)){
          targetNormal = normalHit.normal;
      }
      
      
      if (enableControl){    
      steer = Input.GetAxis("Mouse X");
      
      rigidbody.AddRelativeForce(-targetNormal.up * 1000);
      
      var fwd: float = Input.GetAxis("Vertical");
      rigidbody.AddForceAtPosition (transform.forward * (driveForce * fwd), transform.TransformPoint(Vector3.forward * 1));

      var rgt: float = Input.GetAxis("Horizontal");
      rigidbody.AddForceAtPosition (transform.forward * (driveForce * rgt));
          }
      transform.up = Vector3.Lerp(transform.up, targetNormal, Time.deltaTime * 1);

      rigidbody.AddRelativeForce(transform.right * steer*steerForce);
          
      rigidbody.AddForceAtPosition(transform.right * (steerForce * steer * steerMulti), transform.TransformPoint(Vector3.forward * steerPosZ));
      
      
      if (Physics.Raycast(transform.position, -transform.up, addedhit)) 
          {
              addedforce    = (hoverHeight - addedhit.distance);
              if (addedforce <=0){
              addedforce=0;
          }
          }
      if (addedhit.distance <=2){
          rigidbody.AddRelativeForce(targetNormal.up *(addedforce*20));}
          
      rigidbody.AddRelativeForce(targetNormal.up * (thrustForce*(addedforce*addedforce)));
      
      //Create an array for the vertical thrusters and apply a force to each one.
      for (i = 0; i < thrusters.Length; i++) {
          var wdThruster: Vector3 = transform.TransformPoint(thrusters[i]);
          
          if (Physics.Raycast(wdThruster, -transform.up, hoverHit)) 
          {
              discrep    = (hoverHeight - hoverHit.distance);
              if (discrep <=0.1){discrep=0;}
              
              var upVel: float = rigidbody.GetRelativePointVelocity(wdThruster).y;
              rigidbody.AddForceAtPosition(transform.up * (thrustForce *discrep), wdThruster);
          }
      }
      
      }
      else
      {
           transform.up = Vector3.Lerp(transform.up, Vector3.up, Time.delta time * 1.5);
      }
  }


I solved the aligning issue, but now I cannot steer the vehicle. The issue is caused by the section that aligns the vehicle to the ground (transform.up = Vector3.Lerp(transform.up, targetNormal, Time.deltaTime * 1);). Commenting out that line fixes the issue, because it constantly sets the up axis to zero. How can I match the rotation, but allow the y axis to change?

I just tried transform.LookAt (Vector3 (target.position.x, transform.position.y, target.position.z) and it kind of works, but the vehicle is no longer properly aligned. It won't align to the terrain. Works great on always perfectly flat areas but thats not what I need. I've also already tried directly changing the transform.rotation but as stated before, its being reset to every time FixedUpdate is called.

Comment
Add comment · Show 8
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image hexagonius · Mar 05, 2015 at 10:31 PM 1
Share

Use LookAt with transform.position + steerdirection as first and surface normal as second parameter

avatar image Sylux102 · Mar 05, 2015 at 10:44 PM 0
Share

So for my code I would need to make a new Vector3 for the steer direction right?

EDIT: This partially works, where target is an object childed to my main camera. Problem is its super strict and doesn't really allow for rotation to align (but it sort of does).

transform.LookAt(transform.position + target.TransformDirection(transform.forward), targetNormal);

avatar image Glurth · Mar 06, 2015 at 01:52 PM 0
Share

transform.position + target.TransformDirection(transform.forward) that seems like an odd way to define "steer direction"- if you are looking for a direction towards the target, from the hovercraft, I would have used:

(target.transform.position - hovercraft.transform.position).Normalized()

avatar image Sylux102 · Mar 06, 2015 at 05:27 PM 0
Share

Well I'm using an empty dummy GO as a target. The dummy's y position is always relative to the hovercrafts position. When I rotate the parent of the dummy GO with a mouse look scriptscript locked to the x axis, the hovercraft rotates like I want, but when it needs to align to any floor below it, it refuses to actually align when on any slope greater than about 47 degrees. I'll try your method in a bit.

EDIT: Using the above stated method gives an error exception - $$anonymous$$issing$$anonymous$$ethodException: UnityEngine.Vector3.Normalized

Simply put, I want only roll and pitch to match the floors normals, while only yaw steers.

avatar image Glurth · Mar 06, 2015 at 06:49 PM 0
Share

oops, Normalized is not a function, it's a property - no parens. Normalize() is the function version (which modifies the vector it operates on).

y axis steers: I have not even complied the below (so it might have more typos), but it might be closer to what you are looking for.

 steerDirection = target.transform.position -transform.position;
 float angleOnZXplane = $$anonymous$$athf.ATan(steerDirection.x,steerDirection.z);
 transform.rotation = Quaternion.AngleAxis(angleOnZXplane,surfaceNormal);

Show more comments

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Contour gravity 1 Answer

raycast to determine pivot 1 Answer

How do I align my player transform to waypoints and without restricting Z Axis rotation? 2 Answers

Raycasting around a gameObject while it's rotating 1 Answer

Turret Raycasting Rotation Help 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges