You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity更换父物体后如何保持子物体NAVI的真实缩放值?

问题描述

初始状态下,NAVI作为位置为(0,0,0)的父物体的子物体,其x、y、z轴缩放值为0.15。

(图片说明:展示初始状态下父物体与NAVI的层级关系)

挂载在子物体NAVI上的如下脚本,在保存游戏时会将NAVI的缩放值保存为初始的0.15:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NaviState : MonoBehaviour, IStateQuery
{
    public Transform parentTransform;

    private State m_state = new State();
    private bool once = true;

    public System.Guid UniqueId => System.Guid.Parse("8FBA0A57-81C8-4806-9182-1D0013546288");

    private class State
    {
        public bool isInteractable;
        public bool isChild;
    }

    public string GetState()
    {
        return JsonUtility.ToJson(m_state);
    }

    public void SetState(string jsonString)
    {
        m_state = JsonUtility.FromJson<State>(jsonString);

        if(m_state.isInteractable)
        {
            GetComponent<InteractableItem>().enabledInteraction = true;
        }
        else
        {
            GetComponent<InteractableItem>().enabledInteraction = false;
        }

        if(m_state.isChild)
        {
            transform.GetComponent<InteractableItem>().distance = 0;
            transform.parent = GameObject.Find("rig_f_middle.03.R").transform;
            transform.localPosition = new Vector3(0, 0, 0);
            transform.localRotation = Quaternion.identity;
            transform.localScale = new Vector3(0.15f, 0.15f, 0.15f);
            transform.GetComponent<Collider>().enabled = false;
        }
    }

    private void Update()
    {
        if (GetComponent<InteractableItem>() != null)
        {
            m_state.isInteractable = GetComponent<InteractableItem>().enabledInteraction;
        }

        if(transform.IsChildOf(parentTransform) && once)
        {
            m_state.isChild = true;
            once = false;
        }
    }
}

加载游戏后,NAVI成为玩家手部骨骼的子物体,此时尽管NAVI的localScale仍设为0.15,却显示得异常巨大:

(图片说明:展示加载后NAVI显示过大的效果)

该父物体的位置为(0,0,0),x、y、z轴缩放值为100:

(图片说明:展示玩家手部骨骼父物体的缩放参数为100,100,100)

推测是父物体的100倍缩放导致NAVI显示过大。现咨询:如何在不修改该父物体缩放的前提下,让NAVI保持真实的0.15缩放值?

解决方案

有两种可行的方法可以解决这个问题:

  • 直接计算局部缩放抵消父物体影响
    Unity中子物体的世界缩放是父物体缩放与自身局部缩放的乘积。要让NAVI的世界缩放保持0.15,需要将自身局部缩放设置为目标值除以父物体的缩放。修改SetState方法中设置缩放的代码:

    if(m_state.isChild)
    {
        transform.GetComponent<InteractableItem>().distance = 0;
        var parentTransform = GameObject.Find("rig_f_middle.03.R").transform;
        transform.parent = parentTransform;
        transform.localPosition = new Vector3(0, 0, 0);
        transform.localRotation = Quaternion.identity;
        // 计算抵消父物体缩放后的局部缩放
        Vector3 targetLocalScale = new Vector3(0.15f / parentTransform.localScale.x, 
                                               0.15f / parentTransform.localScale.y, 
                                               0.15f / parentTransform.localScale.z);
        transform.localScale = targetLocalScale;
        transform.GetComponent<Collider>().enabled = false;
    }
    

    如果父物体缩放固定为100倍,也可以直接写死数值:transform.localScale = new Vector3(0.0015f, 0.0015f, 0.0015f);

  • 添加中间空物体层级
    创建一个空物体作为玩家手部骨骼的子物体,将空物体的局部缩放设置为Vector3.one / 100(抵消父物体的100倍缩放),然后把NAVI设为这个空物体的子物体,保持NAVI的局部缩放为0.15即可。这种方式更灵活,后续父物体缩放变化时只需调整中间空物体的缩放。


内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:24:32