在另一个物体表面上放置一个 GameObject 并匹配旋转的方法如何?Unity3D

huangapple go评论68阅读模式
英文:

How would I go about placing a GameObject on another object's surface while matching the rotation? Unity3D

问题

I'm making a game where you build, and when I try to place a GameObject on another one's surface it uses global rotation and not local, however I'm trying to get the placed GameObject's rotation to match the other one. This is hard because I also want to have the placed GameObject's be facing away from the surface, if that makes sense.

I've tried using a raycast hit normal to get the placed GameObject facing the right way, and that works only partly. Its up direction is correct, but the other axis's are not orientated to match the other object. Here's the code:

RaycastHit hit;
if (Physics.Raycast(cameraTransform.position, cameraTransform.TransformDirection(Vector3.forward), out hit, buildingRange, buildable.value))
{
    //Indicator to show where the item will be placed
    buildBall.SetActive(true);
    buildBall.transform.position = hit.point;

    if (Input.GetMouseButtonDown(0))
    {
        //Create the item
        GameObject buildItem = Instantiate(currentItem, Vector3.zero, Quaternion.identity);

        //Set the item's position
        buildItem.transform.position = hit.point;

        //Rotate the item so that it faces away from the other object
        buildItem.transform.up = hit.normal;

        {Connect the buildItem object to the hit.collider.gameObject}
    }
}

I've spent many hours trying numerous solutions, this one yields the closest result.
Here are some pics:

This is what is intended, all blocks are orientated correctly:
在另一个物体表面上放置一个 GameObject 并匹配旋转的方法如何?Unity3D

However when the mass rotates, the blocks that are added on are orientated incorrectly:
在另一个物体表面上放置一个 GameObject 并匹配旋转的方法如何?Unity3D

This got my whole family stumped, but it's gotta be possible.

英文:

I'm making a game where you build, and when I try to place a GameObject on another one's surface it uses global rotation and not local, however I'm trying to get the placed GameObject's rotation to match the other one. This is hard because I also want to have the placed GameObject's be facing away from the surface, if that makes sense.

I've tried using a raycast hit normal to get the placed GameObject facing the right way, and that works only partly. Its up direction is correct, but the other axis's are not orientated to match the other object. Here's the code:

RaycastHit hit;
if (Physics.Raycast(cameraTransform.position, cameraTransform.TransformDirection(Vector3.forward), out hit, buildingRange, buildable.value))
{
    //Indicator to show where the item will be placed
    buildBall.SetActive(true);
    buildBall.transform.position = hit.point;

    if (Input.GetMouseButtonDown(0))
    {
        //Create the item
        GameObject buildItem = Instantiate(currentItem, Vector3.zero, Quaternion.identity);

        //Set the item's position
        buildItem.transform.position = hit.point;

        //Rotate the item so that it faces away from the other object
        buildItem.transform.up = hit.normal;

        {Connect the buildItem object to the hit.collider.gameObject}
    }
}

I've spent many hours trying numerous solutions, this one yields the closest result.
Here are some pics:

This is what is intended, all blocks are orientated correctly:
在另一个物体表面上放置一个 GameObject 并匹配旋转的方法如何?Unity3D

However when the mass rotates, the blocks that are added on are orientated incorrectly:
在另一个物体表面上放置一个 GameObject 并匹配旋转的方法如何?Unity3D

This got my whole family stumped, but it's gotta be possible.

答案1

得分: 1

你需要对其他轴线进行对齐。

因此,您可以使用 hit.normal 作为 GameObject 的新上方向,然后基于此计算其他轴线:

RaycastHit hit;
if (Physics.Raycast(cameraTransform.position, cameraTransform.TransformDirection(Vector3.forward), out hit, buildingRange, buildable.value))
{
    // 用于显示物品将被放置的指示器
    buildBall.SetActive(true);
    buildBall.transform.position = hit.point;

    if (Input.GetMouseButtonDown(0))
    {
        // 创建物品
        GameObject buildItem = Instantiate(currentItem, Vector3.zero, Quaternion.identity);

        // 设置物品的位置
        buildItem.transform.position = hit.point;

        // 基于 hit.normal 和参考方向计算旋转
        Vector3 referenceDirection = Vector3.up; // 您可以根据需要更改此参考方向
        Quaternion rotation = Quaternion.LookRotation(hit.normal, referenceDirection);

        // 将旋转应用于 buildItem
        buildItem.transform.rotation = rotation;

        // 将 buildItem 对象连接到 hit.collider.gameObject
    }
}

这是您提供的代码的中文翻译。

英文:

You need to align the other axes as well.

So you could use the hit.normal as the new up direction for the GameObject, and then calculate the other axes based on that:

RaycastHit hit;
if (Physics.Raycast(cameraTransform.position, cameraTransform.TransformDirection(Vector3.forward), out hit, buildingRange, buildable.value))
{
    // Indicator to show where the item will be placed
    buildBall.SetActive(true);
    buildBall.transform.position = hit.point;

    if (Input.GetMouseButtonDown(0))
    {
        // Create the item
        GameObject buildItem = Instantiate(currentItem, Vector3.zero, Quaternion.identity);

        // Set the item's position
        buildItem.transform.position = hit.point;

        // Calculate the rotation based on the hit.normal and a reference direction
        Vector3 referenceDirection = Vector3.up; // You can change this to your desired reference direction
        Quaternion rotation = Quaternion.LookRotation(hit.normal, referenceDirection);

        // Apply the rotation to the buildItem
        buildItem.transform.rotation = rotation;

        // Connect the buildItem object to the hit.collider.gameObject
    }
}

huangapple
  • 本文由 发表于 2023年6月6日 13:24:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76411637.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定