【问题标题】:Raycasting to make an enemy jump射线投射使敌人跳跃
【发布时间】:2015-11-19 14:55:07
【问题描述】:

如上所述,我正在尝试构建一个简单的游戏,但我似乎无法让敌人正确移动。该游戏是一款 Minecraft 风格的基于块的游戏。到目前为止,我使用的代码使敌人在我进入一定距离时开始跟踪我,并在我离开一定距离后停止跟踪。

我在使用这个脚本时遇到的问题是,当我逃离敌人时,敌人会飘到远处。更重要的是,我一辈子都不能让敌人跳下去。我知道我应该为此使用两个 Raycast:一个检测前面的块,这会使敌人跳起来,另一个检测敌人的下方,如果他脚下没有矿工,让他下降到下面的水平?我不知道如何实现这一点,我们将不胜感激。

我目前的代码如下所示:

var target : Transform; //the enemy's target
var moveSpeed = 3; //move speed
var rotationSpeed = 3; //speed of turning
var range : float=10f;
var range2 : float=10f;
var stop : float=0;
var myTransform : Transform; //current transform data of this enemy

function Awake() {
    myTransform = transform; //cache transform data for easy access/preformance
}
  
function Start() {
    target = GameObject.FindWithTag("1Player").transform; //target the player
}
  
function Update () {
    //rotate to look at the player
    var distance = Vector3.Distance(myTransform.position, target.position);
    if (distance<=range2 &&  distance>=range) {
        myTransform.rotation = Quaternion.Slerp(myTransform.rotation, 
                Quaternion.LookRotation(target.position - myTransform.position),
                rotationSpeed*Time.deltaTime);
    } else if (distance <= range && distance > stop) {
        //move towards the player
        myTransform.rotation = Quaternion.Slerp(myTransform.rotation, 
                Quaternion.LookRotation(target.position - myTransform.position),
                rotationSpeed*Time.deltaTime);
        myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
    } else if (distance <= stop) {
        myTransform.rotation = Quaternion.Slerp(myTransform.rotation, 
                Quaternion.LookRotation(target.position - myTransform.position),
                rotationSpeed*Time.deltaTime);
    }
     
    //lock rotation on x and y axis to zero
    myTransform.eulerAngles = new Vector3(0f, myTransform.eulerAngles.y, 0);
}

【问题讨论】:

    标签: javascript unity3d artificial-intelligence


    【解决方案1】:

    设计真的可以改变很多。这取决于你想要多么聪明的人工智能?它应该是多么现实。首先,您应该检查距离,正如我所见,您这样做了。问题是如果有墙什么的怎么办?也许他们彼此如此接近,但他们之间有一堵墙。这就是你需要光线投射的原因。所以你从敌人向玩家发送光线投射。如果他们之间没有障碍,人工智能可以决定“是的,我应该追你”。但这是现实的另一个问题。如果它不找你怎么办?如果 AI 可以在玩家看向别处时发现玩家,那不是很酷吧?所以你还要检查玩家是否在 AI 前面。也许我们可以这样做:

    var heading = target.position - transform.position;
    var dot: float = Vector3.Dot(heading, transform.forward);
    

    所以如果点是-1,我们可以说它直接在后面,+1 表示在它前面。好吧,现在另一个问题。如果玩家要在AI面前被发现,那么AI就站不住了吧?它应该随机移动和转动。如果您需要,我们可以稍后再做。

    现在还有一个问题,如果你隐藏在一个对象之后怎么办?它应该做什么?我的意思是当你跑步时,如果你和 AI 之间有什么东西,因为光线投射会失败,它会停止跟随你,对吗?我们能为它做些什么?我的建议存储 AI 看到的玩家的最后位置。并且至少去那里检查AI是否可以在那里找到玩家。如果它不能,它可能会继续随机移动。我相信这样做会看起来更真实。

    编辑:哈哈,我意识到我只是改进了你的设计,却忘了回答你到底问了什么。

    首先,AI 应该知道它是否接地。当我们发送光线投射时,我们需要知道的第一距离是我们需要它。

    var distanceToGround = GetComponent<Collider>().bounds.extents.y;
    
    function boolean isGrounded(){
       return Physics.Raycast(transform.position, -Vector3.up, distanceToGround + 0, 1);
    }
    

    AI 应该发送光线投射,而不是从头部发出,更像是在膝盖以下。不要把它发送得太远,只要有一点距离就足够了。只是理解它有一个障碍。并且还发送另一个射线投射,但这次是在膝盖以下。从跳跃高度。如果它没有击中任何东西,我们可以确定存在障碍(第一次光线投射是这样说的),但 AI 可以跳过它(第二次光线投射是这样说的)。决定好之后,如果AI也接地了,就可以跳跃穿越障碍了。

    假设这是第 1 部分。如果你想让我继续讲,我可以为你写另一部分。祝你有美好的一天!

    【讨论】:

    • 非常感谢您的详细回复,但我仍然不确定应该在我已经完成的代码下方添加此代码还是应该替换当前代码中的某些内容我需要做什么?我希望你能帮我完成这个脚本。
    • 好吧,如果你想做我解释的事情,你应该从新的脚本重新开始。遗憾的是,我没有时间在 Unity 上编写和尝试脚本,但我的指示很明确。不是吗?您可以尝试为我所说的所有内容创建一个函数,例如 isGrounded 、 isPlayerInMySight 等。
    猜你喜欢
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多