- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我找到了官方的统一训练https://www.youtube.com/watch?v=D5MqLcO6A8g
并找到错误。(看分数)
我花了大约2天的时间修复它,但失败了。
我找到了“ DontGoThroughThings”脚本,并尝试重写以在2D中使用。再次失败)
请帮我!
这是重写脚本:
public LayerMask layerMask; //make sure we aren't in this layer
public float skinWidth; //probably doesn't need to be changed
private float minimumExtent;
private float partialExtent;
private float sqrMinimumExtent;
private Vector2 previousPosition;
private Rigidbody2D myRigidbody;
//initialize values
void Awake()
{
myRigidbody = GetComponent<Rigidbody2D>();
previousPosition = myRigidbody.position;
minimumExtent = Mathf.Min(Mathf.Min(GetComponent<Collider2D>().bounds.extents.x, GetComponent<Collider2D>().bounds.extents.y));
partialExtent = minimumExtent * (1.0f - skinWidth);
sqrMinimumExtent = minimumExtent * minimumExtent;
}
void FixedUpdate()
{
//have we moved more than our minimum extent?
Vector2 movementThisStep = myRigidbody.position - previousPosition;
float movementSqrMagnitude = movementThisStep.sqrMagnitude;
if (movementSqrMagnitude > sqrMinimumExtent)
{
float movementMagnitude = Mathf.Sqrt(movementSqrMagnitude);
//RaycastHit2D hitInfo;
//check for obstructions we might have missed
if (Physics2D.Raycast(previousPosition, movementThisStep, movementMagnitude, 0, layerMask.value))
myRigidbody.position = (movementThisStep/movementMagnitude)*partialExtent;
Debug.DrawLine(myRigidbody.position, myRigidbody.position - previousPosition, Color.green);
}
previousPosition = myRigidbody.position;
}
最佳答案
说明
Unity中的连续碰撞检测不使用光线投射。结果,非常快速移动(和/或相对较小)的对象(现在将其称为projectile
这种对象)仍然可以穿过物体,而不会检测到碰撞。著名的DontGoThroughThings组件可修复3D问题。有一些不一致之处,但是如果您知道自己在做什么,就可以完成工作。
这是我对其的2D改编。
我添加了一些功能,以使其对每个不太擅长编码或游戏物理的人都更加友好。
如何使用它
将此组件添加到快速移动的对象中,当它们碰到某些东西时,它们将始终触发OnTriggerEnter2D
事件。
您也可以选择发送其他自定义消息(通过更改MessageName
变量)。实际上,由于以下说明,我建议这样做。
发送消息是脚本的主要用例。它不会神奇地使弹丸在物理意义上正确表现。triggerTarget
变量确定是否将消息发送给自身(如果您将打击处理脚本附加到了弹丸上),发送给被打击的对象(如果您将打击处理附加到了应该被打击的对象上)被弹丸击中),或两者的任何变体。
与原始版本不同,此脚本还允许在可以通过momentumTransferFraction
变量进行调整的冲击力上施加力。当两个物体碰撞时,产生的力是两个物体之间动量(质量乘以速度)传递的结果。我这样做的方法很初级,缺少很多促成因素,但是足以让弹丸在撞击时推动物体。就像在现实世界中一样,弹丸越快或越重,施加的力就越大。
还有一些警告(大多数也适用于原始版本)
仅适用于快速移动的物体。使用的次数越少越好,因为它比正常的碰撞检测要昂贵得多。
虽然碰撞检测更准确,但是碰撞分辨率只是非常基本的。它不如物理引擎默认执行的操作好。
在当前版本中,事后总是会发现冲突。这就是为什么您可能会在碰撞记录时看到弹丸穿过物体的原因。我想在不久的将来解决此问题。
如果您在诸如子弹或其他形式的弹丸之类的物体上使用此功能,而这些物体在第一次命中后基本上停止工作,则可以将momentumTransferFraction
设置为1,以使子弹以物理方式推动该对象(通过将其所有动量应用于第一个命中的对象)而无需子弹本身会受到影响。
由于某些原因,您不能仅对一个对象禁用默认的碰撞检测。这意味着,如果您如此(不幸),并且碰巧通过Unity的默认冲突检查记录了碰撞,则可能对同一对象多次触发OnTriggerEnter2D
,或者(如果碰撞器不是触发器)施加对命中目标施加强制作用(除了此脚本施加的目标外)。但是,由于这是随机的并且非常不一致,因此除了在弹丸的对撞机上打开IsTrigger
之外,我建议使用自定义消息名称来处理弹丸的影响。这样,默认冲突检测随机检测到的冲突不会有任何意外的副作用[请记住,默认冲突检测对于此类对象不一致是您添加此脚本的实际原因]。仅供参考:从Unity 5开始,防止默认冲突检测的仅有两种方法是IgnoreCollision和IgnoreLayerCollision。
码
using UnityEngine;
using System.Collections;
using System.Linq;
/// <summary>
/// 2D adaption of the famous DontGoThroughThings component (http://wiki.unity3d.com/index.php?title=DontGoThroughThings).
/// Uses raycasting to trigger OnTriggerEnter2D events when hitting something.
/// </summary>
/// <see cref="http://stackoverflow.com/a/29564394/2228771"/>
public class ProjectileCollisionTrigger2D : MonoBehaviour {
public enum TriggerTarget {
None = 0,
Self = 1,
Other = 2,
Both = 3
}
/// <summary>
/// The layers that can be hit by this object.
/// Defaults to "Everything" (-1).
/// </summary>
public LayerMask hitLayers = -1;
/// <summary>
/// The name of the message to be sent on hit.
/// You generally want to change this, especially if you want to let the projectile apply a force (`momentumTransferFraction` greater 0).
/// If you do not change this, the physics engine (when it happens to pick up the collision)
/// will send an extra message, prior to this component being able to. This might cause errors or unexpected behavior.
/// </summary>
public string MessageName = "OnTriggerEnter2D";
/// <summary>
/// Where to send the hit event message to.
/// </summary>
public TriggerTarget triggerTarget = TriggerTarget.Both;
/// <summary>
/// How much of momentum is transfered upon impact.
/// If set to 0, no force is applied.
/// If set to 1, the entire momentum of this object is transfered upon the first collider and this object stops dead.
/// If set to anything in between, this object will lose some velocity and transfer the corresponding momentum onto every collided object.
/// </summary>
public float momentumTransferFraction = 0;
private float minimumExtent;
private float sqrMinimumExtent;
private Vector2 previousPosition;
private Rigidbody2D myRigidbody;
private Collider2D myCollider;
//initialize values
void Awake()
{
myRigidbody = GetComponent<Rigidbody2D>();
myCollider = GetComponents<Collider2D> ().FirstOrDefault();
if (myCollider == null || myRigidbody == null) {
Debug.LogError("ProjectileCollisionTrigger2D is missing Collider2D or Rigidbody2D component", this);
enabled = false;
return;
}
previousPosition = myRigidbody.transform.position;
minimumExtent = Mathf.Min(myCollider.bounds.extents.x, myCollider.bounds.extents.y);
sqrMinimumExtent = minimumExtent * minimumExtent;
}
void FixedUpdate()
{
//have we moved more than our minimum extent?
var origPosition = transform.position;
Vector2 movementThisStep = (Vector2)transform.position - previousPosition;
float movementSqrMagnitude = movementThisStep.sqrMagnitude;
if (movementSqrMagnitude > sqrMinimumExtent) {
float movementMagnitude = Mathf.Sqrt(movementSqrMagnitude);
//check for obstructions we might have missed
RaycastHit2D[] hitsInfo = Physics2D.RaycastAll(previousPosition, movementThisStep, movementMagnitude, hitLayers.value);
//Going backward because we want to look at the first collisions first. Because we want to destroy the once that are closer to previous position
for (int i = 0; i < hitsInfo.Length; ++i) {
var hitInfo = hitsInfo[i];
if (hitInfo && hitInfo.collider != myCollider) {
// apply force
if (hitInfo.rigidbody && momentumTransferFraction != 0) {
// When using impulse mode, the force argument is actually the amount of instantaneous momentum transfered.
// Quick physics refresher: F = dp / dt = m * dv / dt
// Note: dt is the amount of time traveled (which is the time of the current frame and is taken care of internally, when using impulse mode)
// For more info, go here: http://forum.unity3d.com/threads/rigidbody2d-forcemode-impulse.213397/
var dv = myRigidbody.velocity;
var m = myRigidbody.mass;
var dp = dv * m;
var impulse = momentumTransferFraction * dp;
hitInfo.rigidbody.AddForceAtPosition(impulse, hitInfo.point, ForceMode2D.Impulse);
if (momentumTransferFraction < 1) {
// also apply force to self (in opposite direction)
var impulse2 = (1-momentumTransferFraction) * dp;
hitInfo.rigidbody.AddForceAtPosition(-impulse2, hitInfo.point, ForceMode2D.Impulse);
}
}
// move this object to point of collision
transform.position = hitInfo.point;
// send hit messages
if (((int)triggerTarget & (int)TriggerTarget.Other) != 0 && hitInfo.collider.isTrigger) {
hitInfo.collider.SendMessage(MessageName, myCollider, SendMessageOptions.DontRequireReceiver);
}
if (((int)triggerTarget & (int)TriggerTarget.Self) != 0) {
SendMessage(MessageName, hitInfo.collider, SendMessageOptions.DontRequireReceiver);
}
}
}
}
previousPosition = transform.position = origPosition;
}
}
关于performance - 快速移动物体2D游戏(Unity3d),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29562108/
如何更改循环中变量的名称?比如 number1 、 number2 、 number3 、 number4 ? var array = [2,4,6,8] func ap ( number1: Int
我想设置 View 的背景颜色并在一定延迟后将其更改为另一种颜色。这是我的尝试方式: print("setting color 1") self.view.backgroundColor = UICo
我在使用 express-session 时遇到问题。 session 数据不会在请求之间持续存在。 正如您在下面的代码中看到的那样,/join 路由设置了一些 session 属性,但是当 /sur
我试图从叶渲染器获得一个非常简单的结果,用于快速 Steam 的 for 循环。 我正在上传叶文件 HTML,因为它不接受此处格式正确的代码 - 下面的pizza.swift代码- import
你们中有人有什么好的链接可以与我分享吗?我正在寻找一个 FAST 程序员编辑器,它可以非常快速地打开包含超过 100, 000 行代码的文件?我目前正在使用记事本自动取款机,打开一个 29000 行长
我现在正在处理眼动追踪数据,因此拥有一个巨大的数据集(想想数百万行),因此希望有一种快速的方法来完成此任务。这是它的简化版本。 数据告诉您眼睛在每个时间点正在查看的位置以及我们正在查看的每个文件。 X
我是新手,想为计时器或其他设备选择提示音。 如何打开此列表,以选择其中一种声音? Alert sound list 最佳答案 您将无法在应用中使用系统声音。 但是,您可以包括自己的声音文件,并将其显示
我编写了以下代码来构建具有顺序字符串的数组。 它的工作方式与我预期的一样,但我希望它能更快地运行。有没有更有效的方法在PowerShell中产生我想要的结果? 我是PowerShell的新手,非常感谢
我有一个包含一些非唯一行的矩阵,例如: x 尝试 y <- rle(apply(x, 1, paste, collapse = " ")) # y$lengths is the vector con
我的函数“keyboardWillShown”有问题。所以我想要的是菜单打开时,菜单正好出现在键盘上方。它可以在Iphone 8 plus,8、7、6上完美运行。但是,当我在模拟器上运行Iphone
我正在尝试通过Swift 5中的HTTP get方法从API提取数据。它在启动时成功加载了数据,但是当我刷新页面时,它说“索引超出范围”,这是因为数据是不再会在我的日志中读取,因此索引中没有任何内容。
我想做什么: 从我的数据库中获取时间戳并将其转换为用户的时区。 我的代码: let tryItNow = "\(model.timestampName)" let format = D
给定字体名称和字体大小,如何查找字符串的宽度(CGFloat)? (目标是将UIView的宽度设置为足以容纳字符串的宽度。) 我有两个字符串:一个重复“1”,重复36次,另一个重复“M”,重复36次。
我正在尝试解析此JSON ["Items": ( { AccountBalance = 0; AlphabetType = 3; Description = "\U0631\U
我在UINavigationBar内放置了一个UILabel。 我想根据navigationBar的高度增加该标签的字体大小。当navigationBar很大时,我希望字体大小更大;当滚动并缩小nav
我想将用户输入限制为仅有效数字并使用以下内容: func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, rep
目前我有一个包含超过 100.000 张图像的数据库,它们大小不一或类似,但我想为我的公司制作以下内容: 我插入/上传一张图片,系统返回最有可能相同的图片。我不知道使用什么算法,但它需要快速。我可以预
在我的 swift 项目中,我有一个按钮,我想在标签上打印按下该按钮的时间。 如何解决这个问题? 最佳答案 添加到DHEERAJ的答案中,您只需在func press(sender: UIButton
我必须发表评论,尝试在解析中导入数组。然而,有一个问题。 当我尝试从 Parse 加载数组时,我的输出是 ("Blah","Blah","Blah")这是一个元组...而不是一个数组 TT... 如何
我的应用程序有一个名为 MyDevice 的类,我用它来与硬件通信。该硬件是可选的,实例变量也是可选的: var theDevice:MyDevice = nil 然后,在应用程序中,我必须初始化设备
我是一名优秀的程序员,十分优秀!