【小松教你手游开发】【unity实用技能】父节点下的各个子节点居中摆放

有过一个需求需要一个item,两个item,三个item(不一定有多少个子节点)不同情况都要居中

有两个方法解决:

1.只需要在uiscrollview上的resetPosition 设为0.5,调一下resetPosition自动居中

2.如果本身在uiScrollview上就不能这么用了,两个uiscrollview不能重叠嘛。

所以写了个脚本负责计算每个子节点的localposition。

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

public class CenterChildTransfroms
{
    UIAnchor m_anchor;
    private Transform m_transform;
    private GameObject m_containerGameObject;
    private float m_spacing;

    public CenterChildTransfroms(Transform transform, GameObject containerGameObject,Camera camera, float spacing =0)
    {
        m_transform = transform;
        m_containerGameObject = containerGameObject;
        m_spacing = spacing;

        m_anchor = m_transform.GetComponent<UIAnchor>();
        if (m_anchor == null)
            m_anchor = m_transform.gameObject.AddComponent<UIAnchor>();
        m_anchor.uiCamera = camera;
        m_anchor.container = containerGameObject;
        m_anchor.side = UIAnchor.Side.Center;
        m_anchor.enabled = false;
    }

    public void RepositionChildTransfroms()
    {
        float totalWidth = 0;
        List<Transform> childTrans = new List<Transform>();
        List<float> childTransBoundSizeX = new List<float>();
        foreach (Transform t in m_transform)
        {
            if(t.gameObject.activeSelf)
            {
                childTrans.Add(t);
                float width = (NGUIMath.CalculateRelativeWidgetBounds(t).size.x * t.localScale.x) + m_spacing;
                totalWidth += width;
                childTransBoundSizeX.Add(width);
            }
        }

        if(childTrans.Count > 0)
        {
            //先计算好第一个transform坐标
            childTrans[0].localPosition = new Vector3((-totalWidth / 2 + childTransBoundSizeX[0] / 2), childTrans[0].localPosition.y, childTrans[0].localPosition.z);

            for(int i =1;i<childTrans.Count;i++)
            {
                float lastTransBoundX = childTransBoundSizeX[i - 1] / 2;
                float transBoundX = childTransBoundSizeX[i] / 2;

                childTrans[i].localPosition = new Vector3(childTrans[i - 1].localPosition.x + lastTransBoundX + transBoundX , childTrans[i].localPosition.y,childTrans[i].localPosition.z);
            }
        }
        CenterTransform();
    }

    public void CenterTransform()
    {
        m_anchor.enabled = true;
    }
}

这里可以看到使用前是需要传递父节点transform,居中在哪个GameObject的那个gameObject,传入所属UIcamera,和每个子节点之间间隙。

其实也就是在父节点上添加一个锚点UIAnchor,把需要的参数(cotainerGameObject,Camera)塞进去.

计算时先计算总宽,算出并摆放第一个transform的localPosition,之后根据这个坐标进行一个个计算

时间: 2024-11-12 09:17:58

【小松教你手游开发】【unity实用技能】父节点下的各个子节点居中摆放的相关文章

【小松教你手游开发】【unity实用技能】角色头部跟随镜头旋转

这个在端游上比较场景,在角色展示的时候,当摄像头在角色身边上下左右旋转时,角色头部跟随镜头旋转.如天涯明月刀等. 这个在手游上比较少见,不过实现也没什么区别. 首先一般情况下,找到模型的头部节点,直接用lookAt指向camera就可以了,不过一般需求不会这么简单. 比如说,超过头部扭动极限,头部需要插值回到原始点:当镜头从外部回到极限内,需要插值回来.这时候lookat就没法使用. 更有情况,头部本身坐标系不在世界坐标轴上, 可能旋转了90多或者输出的prefab就是歪的等等,这些情况都没办法

【小松教你手游开发】【系统模块开发】做一个3d旋转菜单

在unity做一个3d旋转菜单,像乱斗西游2的这种: 暂时有两种方法可以实现: 一.当做是2d界面,通过定义几个固定点的坐标.大小.透明度,还有每个点的panel depth大小,把数据存储下来,在手机滑动的过程中计算滑动划过的距离和这个panel大小的比值,乘以两个点之间的距离,获得坐标点移动的距离,通过改变x轴改变位置,同理改变大小和透明度. 这个方法我自己做2d游戏的时候实现过,做起来比较简单,没有什么可拓展性可言,并且会有很多限制,比如拖动过程中很难转变方向.要自己实现运动中的弹性(这里

【小松教你手游开发】【unity实用技能】根据上一个GameObject坐标生成的tips界面

开发游戏,特别是mmo手游的时候经常需要开发的一个需求是,点击某个装备,在它附近的位置生成一个tips界面,介绍装备功能和各种信息. 像上面红色框框里的这个. 这个主要的问题是 根据点击的GameObject对应生成这个详情界面时,详情界面位置需要合理摆放(不能显示不到,不能遮挡等) 基本的思路是, 首先找到GameObject的position, 把手机屏幕大概分成四个象限,知道这个GameObject大概在这个屏幕的哪个象限(左上,左下,右上,右下) 根据象限来判断详情界面应该在GameOb

【小松教你手游开发】【unity系统模块开发】热更

现在的手游项目如果没个热更新迭代根本跟不上, 特别是像我们项目做mmo的更是需要经常改动代码. 而现在的项目一般会选择用lua的方式实现热更新 不过我们项目由于历史原因没有使用,用的是另外一种方案 在项目里的所有GameObject都不挂脚本(NGUI脚本就通过代码的方式挂上),自己写的脚本都不继承Mono并打成dll,然后通过一个启动脚本去打开这些dll. 不过这样就有个问题,ios不能热更... 不管怎么样,先来讲讲这种方案要怎么做. 首先有两部分,一部分是打包,一部分是解包. 而包又分为资

【小松教你手游开发】【unity实用技能】InvalidOperationException: out of sync

在unity开发中出现这个bug. 在网上查了下是在迭代器中直接修改引起的.c#是不允许你在迭代器中直接修改. 改了一下确实解决. 原本是这样 [csharp] view plain copy public void Run() { foreach (var item in timerDict) { if (null != item.Value) { item.Value.Run(); } } } 改成这样: [csharp] view plain copy public void Run()

【小松教你手游开发】【unity实用技能】Unity内存申请和释放(转自tnqiang)

这里先声明转自http://www.jianshu.com/p/b37ee8cea04c 1.资源类型 GameObject, Transform, Mesh, Texture, Material, Shader, Script和各种其他Assets. 2.资源创建方式 静态引用,在脚本中加一个public GameObject变量,在Inspector面板中拖一个prefab到该变量上,然后在需要引用的地方Instantiate: Resource.Load,资源需要放在Assets/Reso

【小松教你手游开发】【unity实用技能】给每个GameObject的打开关闭加上一个渐变

在游戏开发中,经常会因为直接将GameObject,setActive的方式打开关闭,这种方式效果太过生硬而给它加上一个Tween 可能是AlphaTween或者ScaleTween. 再加上一个PlayTween来做控制. 这样子需要在每个GameObject上加上这几个Component不说,还很不好用 所以结合之前用的一个拓展函数的方法,想到一个非常非常方便的方法 (之前的拓展函数文章:http://blog.csdn.net/chrisfxs/article/details/512218

【小松教你手游开发】【unity实用技能】计算目标物体是否在自己的扇形视野范围

在做游戏开发中经常会需要到计算扇形的视野或者是受击范围的时候. 其实这个分为两部分, 第一部分是在扇形距离范围内(也就是不考虑角度,其实是圆形范围内) 第二部分是扇形角度范围内 第一部分很简单,Vector3.Distance(a, b);计算距离 下面讲讲第二部分,扇形角度范围内. 计算怪物是否在你的视野范围内其实可以这么看 Avatar的正方向向量与Avatar到Enemy之间向量的夹角大小是否小于于视线大小的一半. 这样就能判断是否在视线范围内. 所以现在的问题就是这么计算这个夹角 计算的

【小松教你手游开发】【unity实用技能】unity发包优化(android一键发包)

unity本身的发包其实还是挺方便的,国外的游戏基本都用unity本身的发包. 但在国内的游戏有这么多渠道,这个迭代的速度的情况下,就需要一套更高效的发包方式. 接下来讲具体步骤,如果你们项目有热更新会更麻烦一点. 发包优化的目标是做到一键发包,一般发包机会是一台独立的机子,所以 第一步,更新svn 第二步,配置打包信息.根据不同渠道接入不同sdk 第三步,build apk. 因为我们项目暂时还是测试,所以还没做根据不同渠道接入不同sdk.具体思路是写个xml,在上面填写各种配置信息,版本号,

【小松教你手游开发】【unity实用技能】线性差值计算实现

其实这个unity本身就有的函数Mathf.Lerp(),为什么还要自己实现呢. 有一个原因就是这个函数返回的是float型,float型如果数字非常大,转出int时会有精度丢失,也就是转出来的值不对. 而且非常简单. 看下公式 public int Lerp(int a,int b,int v) { return (int)(a - (0 - v) / (0 - 1) * (a - b)): } 原文地址:http://blog.51cto.com/13638120/2084965