设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 1891|回复: 4
打印 上一主题 下一主题

[Unity] 请教碰撞点的法线向量长度问题

[复制链接]

Lv4.逐梦者

梦石
0
星屑
10603
在线时间
2012 小时
注册时间
2013-6-10
帖子
1496
跳转到指定楼层
1
发表于 2022-8-20 19:35:22 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
不知是否有高手知道。。。代码我贴到最后了。
今日我在学习unity的书时,跟着走到了实现角色移动的步骤,其中涉及到了主角是否站在地面上的检测。以下是各碰撞盒的体积及分布情况(就是那个浅浅的绿绿的框)。这两张图的左下角把法线向量长度打印了出来。
可以看到,与地面垂直碰撞法线长度是1,与地面和障碍物碰撞法线长度变成0.22,我就想问,为什么
为什么与地面垂直碰撞法线长度是1,为什么与地面和障碍物碰撞法线长度变成0.22?




其中,角色的碰撞盒半径0.5。

我开始想会不会和主角圆形碰撞盒的半径有关系啊?但是半径怎么修改法线长度还是1!
我实在无法理解这个法线向量是怎么回事,无法想象这个法线向量的位置是从那里开始到那里结束的。

以下是我的Player代码,是很常规的实现,对unity比较熟练的人来说应该不难阅读。
RUBY 代码复制
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class PlayerController : MonoBehaviour
  6. {
  7.     private Transform playerTransform;
  8.     private Rigidbody2D body;
  9.     public float speed= 2f;
  10.     private bool onGround;
  11.     public float jumpPower = 150;
  12.     // Start is called before the first frame update
  13.     void Start()
  14.     {
  15.         body = GetComponent<Rigidbody2D>();
  16.         onGround = false;
  17.     }
  18.  
  19.     // Update is called once per frame
  20.     private void FixedUpdate()
  21.     {
  22.         KeyboardControl();
  23.     }
  24.     //碰撞对象脱离与主角的碰撞时
  25.     private  void OnCollisionExit2D(Collision2D collision)
  26.     {
  27.         onGround = false;
  28.     }
  29.     //碰撞对象与主角碰撞并保持接触时
  30.     private void OnCollisionStay2D(Collision2D collision)
  31.     {
  32.         int cnum = collision.contactCount;//获得碰撞点数量
  33.         for(int i = 0;i<cnum;i++){
  34.             ContactPoint2D contact = collision.GetContact(i);
  35.             Debug.Log(contact.normal.y);//前两张图左下角显示了法线向量长度的结果
  36.             if(contact.normal.y > 0.8f){
  37.                 if(!onGround){
  38.                     onGround  = true;
  39.                 }
  40.             }
  41.         }
  42.     }
  43.  
  44.     private void KeyboardControl(){
  45.         float sp = speed * Input.GetAxis("Horizontal");
  46.         body.velocity = new Vector2(sp,body.velocity.y);
  47.         if(onGround){
  48.             if(Input.GetAxis("Vertical")> 0.0f)
  49.             {body.AddForce(new Vector2(0.0f,jumpPower));}
  50.         }
  51.     }
  52. }

Lv4.逐梦者

梦石
9
星屑
5143
在线时间
746 小时
注册时间
2017-5-18
帖子
203

极短22获奖

2
发表于 2022-8-22 02:41:52 | 只看该作者
本帖最后由 zeniusi193 于 2022-8-22 03:23 编辑

翻这问题串可以解决大部份Unity内关於这块的问题
https://forum.unity.com/threads/ ... l-inaccurate.77025/

之后关於normal法线

首先你这里,如果在档杆边上,应该是同时print了1.0和0.22,而你因为只有一行只显示了0.22。。。

然后
Normal 法线是个3维数值
(虽然2d可以闭眼不看其中一个数字)
代表一个面向,如果没有特定一个基准
就是按世界xyz轴来算
每一个平行於xyz轴的线都是(1/0/0)(0/1/0)这类的数字
所以你这个和地面的碰撞就会是1.0
(如果另外定基准就是按那个基准来算,详细可以找一下3D法线和法线贴图的概念了解一下)

你人物面向障碍物不是平行於xyz上
那自然会是一个类似(0/0.22***/0.*****)的东西
把xyz全print 出来
再把你地面各种转一下角度看看碰撞结果就知道了

Normal可以跟角度转换
查一下转换公式会更好理解
(我忘了是sin还是cos还是tan~~~~~

后面做按斜率改变材质之类的东西
(比如草地及墙壁,下雨在材质上是会积水还是有流水)
normal 这块就很重要,可以多花时间看看

点评

原来如此!太感谢了!!  发表于 2022-8-22 10:29

评分

参与人数 2星屑 +100 梦石 +1 +2 收起 理由
死伤殆尽 + 100 + 1 + 1 认可答案
小怪兽奇奇侠 + 1 认可答案 + 精品文章

查看全部评分

回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
10603
在线时间
2012 小时
注册时间
2013-6-10
帖子
1496
3
 楼主| 发表于 2022-9-14 00:55:15 | 只看该作者
@tuxyin 我才知道原来这是你写的书
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1282
在线时间
257 小时
注册时间
2021-2-16
帖子
247
4
发表于 2022-10-28 19:24:03 | 只看该作者
本帖最后由 tuxyin 于 2022-10-28 19:37 编辑
小怪兽奇奇侠 发表于 2022-9-14 00:55
@tuxyin 我才知道原来这是你写的书


感谢小怪兽购买支持!现在回过头看,书写的其实挺……那啥的 ……
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-24 08:36

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表