transform 订阅
transform是一个函数命令,应用于指定范围的每个元素。 展开全文
transform是一个函数命令,应用于指定范围的每个元素。
信息
类    别
函数
作    用
应用于指定范围的每个元素
来    源
标准库
外文名
transform
transform解释
标准库 中的 transform
收起全文
精华内容
下载资源
问答
  • transform: scale();缩放在IE浏览器下会有抖动 transform缩放在IE浏览器下会有抖动 可以在缩放的同时添加一个旋转 如: transform: scale(1.2); 换成: transform: scale(1.2) rotate(0.1deg); transform:...
  • transform

    千次阅读 2018-09-03 13:30:00
    transform属性向元素应用 2D 或 3D 转换。允许我们对元素进行旋转、缩放、移动或倾斜。 Internet Explorer 10、Firefox、Opera 支持 transform 属性。 Internet Explorer 9 支持替代的 -ms-transform 属性(仅适用...

    transform属性向元素应用 2D 或 3D 转换。允许我们对元素进行旋转、缩放、移动或倾斜。
    Internet Explorer 10、Firefox、Opera 支持 transform 属性。
    Internet Explorer 9 支持替代的 -ms-transform 属性(仅适用于 2D 转换)。
    Safari 和 Chrome 支持替代的 -webkit-transform 属性(3D 和 2D 转换)。
    Opera 只支持 2D 转换。

    语法

    transform: none|transform-functions; 
    

    用法

    描述测试
    none定义不进行转换。
    matrix(n,n,n,n,n,n)定义 2D 转换,使用六个值的矩阵。matrix.html
    matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n)定义 3D 转换,使用 16 个值的 4x4 矩阵。
    translate(x,y)定义 2D位移转换。translate.html
    translate3d(x,y,z)定义 3D位移转换。
    translateX(x)定义位移转换,只是用 X 轴的值。
    translateY(y)定义位移转换,只是用 Y 轴的值。
    translateZ(z)定义 3D位移转换,只是用 Z 轴的值。
    scale(x,y)定义 2D 缩放转换。scale.html
    scale3d(x,y,z)定义 3D 缩放转换。
    scaleX(x)通过设置 X 轴的值来定义缩放转换。
    scaleY(y)通过设置 Y 轴的值来定义缩放转换。
    scaleZ(z)通过设置 Z 轴的值来定义 3D 缩放转换。
    rotate(angle)定义 2D 旋转,在参数中规定角度,不过必须要有单位,比如deg(度), turn(圈), grad(百分度 – 一种角的测量单位,定义为一个圆周角的1/400。常用于建筑或土木工程的角度测量),甚至可以使用calc()计算,例如:calc(.25turn - 30deg)。rotate.html
    rotate3d(x,y,z,angle)定义 3D 旋转。
    rotateX(angle)定义沿着 X 轴的 3D 旋转。
    rotateY(angle)定义沿着 Y 轴的 3D 旋转。
    rotateZ(angle)定义沿着 Z 轴的 3D 旋转。
    skew(x-angle,y-angle)定义沿着 X 和 Y 轴的 2D 倾斜转换。skew.html
    skewX(angle)定义沿着 X 轴的 2D 倾斜转换。
    skewY(angle)定义沿着 Y 轴的 2D 倾斜转换。
    perspective(n)为 3D 转换元素定义透视视图。

    transform-origin

    transform旋转默认是绕着中心点旋转的,而这个中心点就是transform-origin属性对应的点。该属性必须与 transform属性一同使用。
    Internet Explorer 10、Firefox、Opera 支持 transform-origin 属性。
    Internet Explorer 9 支持替代的 -ms-transform-origin 属性(仅适用于 2D 转换)。
    Safari 和 Chrome 支持替代的 -webkit-transform-origin 属性(3D 和 2D 转换)。Opera 只支持 2D 转换。
    语法为:

    transform-origin: x-axis y-axis z-axis;
    
    描述
    x-axis定义视图被置于 X 轴的何处。可能的值:left、center、right、length、%
    y-axis定义视图被置于 Y 轴的何处。可能的值:top、center、bottom、length、%
    z-axis定义视图被置于 Z 轴的何处。可能的值:length

    参考实例:transform-origin.html

    transform-stype

    规定如何在 3D 空间中呈现被嵌套的元素。该属性必须与 transform属性一同使用。
    Firefox 支持 transform-style 属性。Chrome、Safari 和 Opera 支持替代的 -webkit-transform-style 属性。
    语法为:

    transform-style: flat|preserve-3d;
    
    描述
    flat子元素将不保留其 3D 位置。
    preserve-3d子元素将保留其 3D 位置。

    text-transform

    还有一个带transform属性的就是text-transform,这个和transform本事没有太大关系,它是控制文本的大小写的。里面有以下属性:

    描述
    none默认。定义带有小写字母和大写字母的标准的文本。
    capitalize文本中的每个单词以大写字母开头。
    uppercase定义仅有大写字母。
    lowercase定义无大写字母,仅有小写字母。
    inherit规定应该从父元素继承 text-transform 属性的值。

    transform一般会和transition、animation一起使用,这里有这三个属性的对比:transition,transform,animation对比

    展开全文
  • 主要介绍了css3的transform造成z-index无效解决方案,需要的朋友可以参考下
  • div css3 hover transform属性5种鼠标悬停 div css3 hover transform属性5种鼠标悬停
  • 主要介绍了Java xml出现错误 javax.xml.transform.TransformerException: java.lang.NullPointerException的相关资料,需要的朋友可以参考下
  • css3属性transform制作圆盘导航菜单代码 css3属性transform制作圆盘导航菜单代码 css3属性transform制作圆盘导航菜单代码 css3属性transform制作圆盘导航菜单代码
  • 本文将详细介绍关于transform变形3D的内容,但需以了解transform变形2D为基础。3D变形涉及的属性主要是transform-origin、transformtransform-style、perspective、perspective-origin、backface-visibility。一起...
  • Transform

    千次阅读 2015-11-01 22:51:40
    Transform 继承自:Component 一个对象的位置、旋转和缩放。 场景中每个对象都有一个Transform。它被用来存储和操作对象的位置、旋转和缩放。每一个Transform都可以有一个父级,允许你分层次的运用位置、旋转和...

    http://docs.unity3d.com/ScriptReference/Transform.html


    Transform

    继承自:Component


    一个对象的位置、旋转和缩放。

    场景中每个对象都有一个Transform。它被用来存储和操作对象的位置、旋转和缩放。每一个Transform都可以有一个父级,允许你分层次的运用位置、旋转和缩放。Hierarchy面板有层级关系。他们也支持计数器,所以你可以遍历子物体。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            foreach (Transform child in transform) {
                child.position += Vector3.up * 10.0F;
            }
        }
    }

    Variables

    childCount

    类型:int

    Transform的子物体的个数。(只返回一级子物体的个数,子物体下的子物体不计数)

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            print(transform.childCount);
        }
    }

    eulerAngles

    类型:Vector3

    以角度为单位,以欧拉角计算的旋转。

    x, y, z角代表绕z轴旋转z度,绕x轴旋转x度,绕y轴旋转y度。

    仅使用这个变量来读取和设置脚的绝对的值。不要递增他们,超过360度时它将失败。使用Transform.Rotate来代替。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        public float yRotation = 5.0F;
        void Update() {
            yRotation += Input.GetAxis("Horizontal");
            transform.eulerAngles = new Vector3(10, yRotation, 0);
        }
        void Example() {
            print(transform.eulerAngles.x);
            print(transform.eulerAngles.y);
            print(transform.eulerAngles.z);
        }
    }
    不要单独的设置一个轴的角度,因为它将导致偏移和不希望的旋转。当设置一个新值时,一次性全部设置他们,就像上面所示。unity会转换欧拉角度到Transform.rotation或将Transform.rotation转换到欧拉角度。


    forward

    类型:Vector3

    世界坐标系中蓝色的轴,也就是Z轴。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        public float thrust;
        public Rigidbody rb;
        void Start() {
            rb = GetComponent<Rigidbody>();
        }
        void Update() {
            rb.AddForce(transform.forward * thrust);
        }
    }
    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        public float angleBetween = 0.0F;
        public Transform target;
        void Update() {
            Vector3 targetDir = target.position - transform.position;
            angleBetween = Vector3.Angle(transform.forward, targetDir);
        }
    }
    hasChanged

    类型:bool

    上一次这个标签设置为fsalse后transform改变过吗?

    对变换的任何改变会导致矩阵的重新计算:任意调节它的位置、旋转或缩放。请注意此操作,是否在设置此标识之前新旧的值不同,也将不会实际检查。因此,对于实例化,transform.position将总是设置此变换的hasChanged,无论是否有实际的变化。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Update() {
            if (transform.hasChanged) {
                print("The transform has changed!");
                transform.hasChanged = false;
            }
        }
    }
    localEulerAngle

    类型:Vector3

    以角度为单位,相对于父级transform的旋转。

    x, y, z角度代表绕z轴旋转z度,绕x轴旋转x度,绕y轴旋转y度。

    仅使用这个变量去读取和设置绝对的角度的值。不要递增它们,当角度超过360度时它将失败,使用Transform.Rotate代替。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            print(transform.localEulerAngles.x);
            print(transform.localEulerAngles.y);
            print(transform.localEulerAngles.z);
        }
    }
    Unity自动转换这些角度到Transform.loaclRotation,反之亦然。


    localPosition

    类型:Vector3

    相对于父级transform,当前transform的位置。

    如果当前transform没有父级,它与Transform.position的值一样。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            transform.localPosition = new Vector3(0, 0, 0);
            print(transform.localPosition.y);
        }
    }
    注意当计算世界坐标系的位置时,父级transform的世界坐标系的旋转和缩放会作用于当前位置。也就是说,Transform.position的1unit就是1unit,而transform.localposition的1unit会因为父级的缩放而缩放。


    localScale

    类型:Vector3

    相对于父级transform,当前transform的缩放。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            // Widen the object by 0.1
            transform.localScale += new Vector3(0.1F, 0, 0);
        }
    }

    localRotation

    类型:Quaternion

    相对于父级transform,当前transform的旋转。

    Unity以四元数来存储rotation。要旋转一个对象,使用Transform.Rotate。要以欧拉角度来改变旋转,使用Transform.localEulerAngles。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            transform.localRotation = Quaternion.identity;
        }
    }

    localToWorldMatrix

    类型:matrix4x4

    一个点从自身坐标系转换到世界坐标系的矩阵。(只读)

    如果你对使用矩阵来转换坐标不熟悉,使用 Transform.TransformPoint代替。

    重要:如果你在设置着色器参数你必须使用Renderer.localToWoldMarix代替。



    lossyScale

    类型:Vector3

    对象的全局缩放(只读)(世界坐标系的缩放)

    请注意如果你有一个缩放的父级transform并且子级是任意旋转,那么这个缩放有偏差。因此缩放不能由3个组件的向量正确表示,而是用3X3的矩阵。然而这种表述方式工作起来非常不方便。lossyScale是一个非常方便的属性来表示真实世界的缩放。如果你的对象没有偏差,这个值将是完全正确的,如果物体包含偏差,这个值也不会有很大不同。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            print(transform.lossyScale);
        }
    }
    (这个值就是物体在世界坐标系中的缩放,缩放是有损的是因为并不精确,它就是错误的如果它的一个或者多个父级有不同的x, y, z的缩放或者旋转。如果父级的缩放是统一的那么它就是完全正确的。如果父级的旋转是:0.1,0.5,0.4,lossyScale会接近但并不是非常精确。如果父级的缩放是:0.1,0.1,0.1,lossyScale是精确的。)


    parent

    类型:Transform

    transform的父级

    改变父级会改变相对于父级的位置、缩放和旋转信息,但是不会改变世界坐标系的位置、旋转和缩放。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour
    {
    	public GameObject player;
    
    	//Invoked when a button is pressed.
    	public void Example(GameObject newParent)
    	{
    		//Makes the GameObject "newParent" the parent of the GameObject "player".
    		player.transform.parent = newParent.transform;
    			
    		//Display the parent's name in the console.
    		Debug.Log ("Player's Parent: " + player.transform.parent.name);
    
    		// Check if the new parent has a parent GameObject.
    		if(newParent.transform.parent != null)
    		{
    			//Display the name of the grand parent of the player.
    			Debug.Log ("Player's Grand parent: " + player.transform.parent.parent.name);
    		}
    	}
    }
    另一个例子:

    // Detaches the transform from its parent.
    	transform.parent = null;

    position

    类型:Vector3

    transform在世界坐标系的位置

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            transform.position = new Vector3(0, 0, 0);
            print(transform.position.x);
        }
    }
    right

    类型:Vector3

    对象的自身坐标系的x轴在世界坐标系中指向的方向。


    root

    类型:Transform

    层级关系中最上层的transform。

    (永远不会返回null,如果transform没有父级则返回他自己)

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void OnCollisionEnter(Collision collision) {
            if (collision.transform.root != transform.root)
                print("The colliding objects are not in the same hierarchy");
            
        }
    }
    rotation

    类型:Quaternion

    保存在四元数中的transform在世界坐标系中的旋转。

    Unity以四元数保存旋转。要旋转一个对象,使用Transform.Rotate。要以欧拉角设置旋转,使用Transform.eulerAngles

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            transform.rotation = Quaternion.identity;
        }
    }
    另一个例子:

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        public float smooth = 2.0F;
        public float tiltAngle = 30.0F;
        void Update() {
            float tiltAroundZ = Input.GetAxis("Horizontal") * tiltAngle;
            float tiltAroundX = Input.GetAxis("Vertical") * tiltAngle;
            Quaternion target = Quaternion.Euler(tiltAroundX, 0, tiltAroundZ);
            transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * smooth);
        }
    }
    up

    类型:Vector3

    世界坐标系中,transform的绿色的轴。


    worldToLocalMatrix

    类型:Matrix4x4

    矩阵转换一个点从世界坐标系到自身坐标系(只读)

    如果你不熟悉使用矩阵来转换坐标,使用Transform.InverseTransformPoint 代替

    重要:如果设置着色器参数,你必须使用Renderer.worldToLocalMatrix代替




    Public Functions

    DetachChildren

    类型:void DetachChildren()

    和所有子级解除父子关系。

    如果你想销毁一个层级关系的根对象而不想销毁子对象,会用到这个函数。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Example() {
            transform.DetachChildren();
            Destroy(gameObject);
        }
    }
    Find

    类型:Transform Find(string name)

    参数:

    name: 要找的子级的名字。


    通过name找到一个子级并返回它。

    如果没有找到name子级,返回null。如果name包含一个'/'字符,它会将其作为层级的路径名。(只返回一级子级,多级子级必须按路径查找)

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour
    {
    	public GameObject player;
    	public GameObject gun;
    	public Transform ammo;
    
    	//Invoked when a button is clicked.
    	public void Example()
    	{
    		//Finds and assigns the child of the player named "Gun".
    		gun = player.transform.Find("Gun").gameObject;
    
    		//If the child was found.
    		if(gun != null)
    		{
    			//Find the child named "ammo" of the gameobject "magazine" (magazine is a child of "gun").
    			ammo = gun.transform.Find("magazine/ammo");
    		}
    		else Debug.Log("No child with the name 'Gun' attached to the player");
    	}
    }

    GetChild

    类型:Transform GetChild(int index)

    参数:

    index: 要返回的子transform的索引。必须比Transform.childCount小。

    返回:  索引为index的子级transform

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour
    {
    	public Transform meeple;
    	public GameObject grandChild;
    
    	public void Example()
    	{
    		//Assigns the transform of the first child of the Game Object this script is attached to.
    		meeple = this.gameObject.transform.GetChild(0);
    
    		//Assigns the first child of the first child of the Game Object this script is attached to.
    		grandChild = this.gameObject.transform.GetChild(0).GetChild(0).gameObject;
    	}
    }

    GetSiblingIndex

    类型:int GetSiblingIndex()


    会的同级索引。(即自己在所在层级的索引)



    InverseTransformDirection

    类型:Vector3 InverseTransformDirection(Vector3 direction)


    从世界坐标系转换一个direction到自身坐标系。与Transform.TransformDirection相反

    这个操作不受缩放影响。

    你用该使用Transform.InverseTransformPoint如果向量是空间的点而不是方向。


    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        private Vector3 relative;
        void Example() {
            relative = transform.InverseTransformDirection(Vector3.forward);
            Debug.Log(relative);
        }
    }
    2. public  Vector3  InverseTransformDirection(float x, float y, float z)

    同上

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        private Vector3 relative;
        void Example() {
            relative = transform.InverseTransformDirection(0, 0, 1);
            Debug.Log(relative);
        }
    }



    InverseTransformPoint

    类型:Vector3 InverseTransformPoint(Vector3 position)


    将position从世界坐标系转换到自身坐标系。

    这个函数与Transform.TransformPoint相反,后者被用来从自身坐标系转换到世界坐标系。

    注意返回值受缩放影响。如果你在处理方向向量而不是位置向量,使用Transform.InverseTransformDirection。

    	// Calculate the transform's position relative to the camera.
    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        public Transform cam;
        public Vector3 cameraRelative;
        
        void Start() {
    		cam = Camera.main.transform;
    		Vector3 cameraRelative = cam.InverseTransformPoint(transform.position);
    
            if (cameraRelative.z > 0)
                print("The object is in front of the camera");
            else
                print("The object is behind the camera");
        }
    }
    2.  public  Vector3  InverseTransformPoint (float  x , float  y , float  z );

    同上

    	// Calculate the world origin relative to this transform.
    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Start() {
            Vector3 relativePoint = transform.InverseTransformPoint(0, 0, 0);
            
            if (relativePoint.z > 0)
                print("The world origin is in front of this object");
            else
                print("The world origin is behind of this object");
        }
    }

    InverseTransformVector

    类型:Vector3 InverseTransformVector(Vector3 vector)

    将一个vector从世界坐标系转换到自身坐标系。Transform.TransformVector函数的反面。受缩放影响。


    2.  public Vector3 InverseTransformVector(float x, float y, float z);

    同上



    IsChildOf

    类型:bool IsChildOf(Transform parent)

    当前的transform是否是parent的子级?

    返回一个布尔值表明这个transform是否是给出的transform的子级。如果这个transform是个子级、多级子级(子级的子级)或完全就是它自己,返回true,否则返回false。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void OnTriggerEnter(Collider col) {
            if (col.transform.IsChildOf(transform))
                return;
            
            print("Do something here");
        }
    }

    LookAt

    类型: void LookAt(Transform target, Vector3 worldUp = Vector3.up);

    参数:

    target : 要朝向的对象

    worldUp: 指定向上的方向的向量


    旋转transform,使前方朝向target的位置。

    然后它旋转transform使他的向上的方向向量指向worldup向量示意的方向。如果worldup参数为空,函数默认使用世界坐标系y轴。worldup只是一个示意向量。如果向前的方向垂直于worldup,向上的向量只匹配worldup向量。

    // This complete script can be attached to a camera to make it 
    	// continuously point at another object.
    	
    	// The target variable shows up as a property in the inspector. 
    	// Drag another object onto it to make the camera look at it.
    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        public Transform target;
        
        void Update() {
        	// Rotate the camera every frame so it keeps looking at the target 
            transform.LookAt(target);
        }
    }
    2.   public void  LookAt ( Vector3  worldPosition Vector3  worldUp  = Vector3.up);

    同上


    Rotate

    类型:Rotate(Vector3 eulerAngles, Soace relativeTo=Space.Self)


    绕z轴旋转eulerAngles.z度,绕x轴旋转eulerAngles.x度,绕y轴旋转eulerAngles.y度(按照这个顺序)。

    如果没有设置relativeTo,旋转绕着自身坐标系旋转。如果relativeTo设置为Space.World,绕世界坐标系旋转

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Update() {
            transform.Rotate(Vector3.right * Time.deltaTime);
            transform.Rotate(Vector3.up * Time.deltaTime, Space.World);
        }
    }
    2.  public void  Rotate (float  xAngle , float  yAngle , float  zAngle Space relativeTo  = Space.Self);

    同上


    3.  public void Rotate(Vector3 axis, float angleSpace relativeTo = Space.Self);

    绕着axis旋转angle度。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Update() {
            transform.Rotate(Vector3.right, Time.deltaTime);
            transform.Rotate(Vector3.up, Time.deltaTime, Space.World);
        }
    }


    RotateAround

    类型: void RotateAround(Vector3 point, Vector3 axis, float angle);


    世界坐标系中,绕着穿过point点的axis轴旋转angle度。

    这个函数同时改变transform的位置和旋转

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Update() {
            transform.RotateAround(Vector3.zero, Vector3.up, 20 * Time.deltaTime);
        }
    }

    SetAsFirstSibling

    类型:void SetAsFirstSibling()


    移动transform到自身所在transform列表的开端。(把transform移动到当前层级的第一个位置)

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI; //Required when using UI Elements.
    using UnityEngine.EventSystems; // Required when using event data.
    
    public class ExampleClass : MonoBehaviour, IPointerDownHandler
    {
    	public RectTransform panelRectTransform;
    
    	//Invoked when the mouse pointer goes down on a UI element. 
    	public void OnPointerDown (PointerEventData data) 
    	{
    		// Puts the panel to the back as it is now the first UI element to be drawn.
    		panelRectTransform.SetAsFirstSibling ();
    	}
    }

    SetAsLastSibling

    类型: void SetAsLastSibling();

    移动transform到transform列表的末端。

    using UnityEngine;
    using System.Collections;
    using UnityEngine.UI; //Required when using UI Elements.
    using UnityEngine.EventSystems; // Required when using event data.
    
    public class ExampleClass : MonoBehaviour, IPointerDownHandler
    {
    	public RectTransform panelRectTransform;
    
    	//Invoked when the mouse pointer goes down on a UI element. 
    	public void OnPointerDown (PointerEventData data) 
    	{
    		// Puts the panel to the front as it is now the last UI element to be drawn.
    		panelRectTransform.SetAsLastSibling ();
    	}
    }

    SetParent

    类型: void SetParent(Transform parent, bool worldPositionStays)

    参数:

    parent: transform要使用的父级

    worldPositionStays: 如果为真,相对父级的位置、缩放和旋转被改变所以对象可以保持以前的世界坐标系中的位置、旋转和缩放。


    设置transform的父级。

    这个函数与parent属性一样,除了它可以通过设置worldPositionStays属性为false让transform保持他的局部坐标不变。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour
    {
    	public GameObject player;
    
    	//Invoked when a button is clicked.
    	public void Example(Transform newParent)
    	{
    		//Sets "newParent" as the new parent of the player GameObject.
    		player.transform.SetParent(newParent);
    
    		//Same as above, except this makes the player keep its local orientation rather than its global orientation.
    		player.transform.SetParent(newParent, false);
    	}
    }

    SetSiblingIndex

    类型:void SetSiblingIndex(int index)

    参数:

    index: 设置的索引


    设置当前层级索引。


    TransformDirection

    类型:Vector3 TransformDirection(Vection direction)


    把direction从自身坐标系转换到世界坐标系。

    这个操作不受transform的缩放和位置影响。

    返回的向量与direction长度相同。

    如果向量代表的是一个位置而不是方向,使用Transform.TransformPoint。


    2. public Vector3 TransformDirection(float x, float y, float z);

    同上



    TransformPoint

    类型:Vector3 TransformPoint(Vector3 position)


    把position从自身坐标系转换到世界坐标系

    注意返回的位置受缩放影响。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        public GameObject someObject;
        public Vector3 thePosition;
        
        void Start() {
        	// Instantiate an object to the right of the current object
    	    thePosition = transform.TransformPoint(Vector3.right * 2);
    	    Instantiate(someObject, thePosition, someObject.transform.rotation);
        }
    }
    2.  public  Vector3  TransformPoint (float  x , float  y , float  z );

    同上

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        public GameObject someObject;
        
        void Start() {
        	// Instantiate an object to the right of the current object
            Vector3 thePosition = transform.TransformPoint(2, 0, 0);
            Instantiate(someObject, thePosition, someObject.transform.rotation);
        }
    }

    TransformVector

    类型: Vector3 TransformVector(Vector3 vector)

    操作不受transform的位置影响,但是受缩放影响。返回的向量可能与vector长度不一样。


    2. public Vector3 TransformVector(float x, float y, float z);

    同上



    Translate

    类型:void Translate(Vector3 translation, Space relativeTo=Space.Self)


    将transform以translation的方向和距离移动。

    如果relativeTo没有设置或设置为Space.Self,移动是相对于自身坐标系。如果relativeTo设置为Space.World,移动是相对于世界坐标系。

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Update() {
            transform.Translate(Vector3.forward * Time.deltaTime);
            transform.Translate(Vector3.up * Time.deltaTime, Space.World);
        }
    }

    2.public void Translate(float x, float y, float zSpace relativeTo = Space.Self);

    同上

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Update() {
            transform.Translate(0, 0, Time.deltaTime);
            transform.Translate(0, Time.deltaTime, 0, Space.World);
        }
    }

    3.public void Translate(Vector3 translationTransform relativeTo);

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Update() {
            transform.Translate(Vector3.right * Time.deltaTime, Camera.main.transform);
        }
    }

    4.public void Translate(float x, float y, float zTransform relativeTo);

    using UnityEngine;
    using System.Collections;
    
    public class ExampleClass : MonoBehaviour {
        void Update() {
            transform.Translate(Time.deltaTime, 0, 0, Camera.main.transform);
        }
    }

    展开全文
  • local transform = Transform. new (player) transform: R6 () transform: R15 () transform: ChangeRigType ( " R6 " ) transform: ChangeRigType (Enum. HumanoidRigType . R6 ) 客户 require (path. to . ...
  • Fourier Transform Spectral Methods
  • Transform详解

    万次阅读 多人点赞 2020-08-18 18:50:55
    1、Transform简介 Transformer中抛弃了传统的CNN和RNN,整个网络结构完全是由Attention机制组成。更准确地讲,Transformer由且仅由self-Attenion和Feed Forward Neural Network组成。一个基于Transformer的可训练的...

    目录

    1、Transform简介

    2、Transform结构

    3、Transform encoder过程

    4、Attention

    5、Self-Attention

    5.1、self-Attention细节描述  

    5.2、矩阵运算过程描述

    6、Multi-Head Attention  

    7、Transform的encoder整体结构

    8、自注意机制的复杂度

    9、Positional Encoding

    10、残差模块和Layer normalization

    10.1、残差引入目的

    10.2、Normalization引入目的

    11、Decoder层

    11.1、Mask

    11.2、Padding Mask

    11.3、Sequence mask

    11.4、解码过程

    12、输出层

    13、 优缺点总结


    1、Transform简介

    Transformer中抛弃了传统的CNNRNN,整个网络结构完全是由Attention机制组成。更准确地讲,Transformer由且仅由self-AttenionFeed Forward Neural Network组成。一个基于Transformer的可训练的神经网络可以通过堆叠Transformer的形式进行搭建,作者的实验是通过搭建编码器和解码器各6层,总共12层的Encoder-Decoder,并在机器翻译中取得了BLEU值得新高。

    2、Transform结构

    Transformer的实验基于机器翻译

    Transform本质是Encoder-Decoder的结构

    论文中所设置的,编码器由6个编码block组成,同样解码器是6个解码block组成。与所有的生成模型相同的是,编码器的输出会作为解码器的输入,如图3所示:

    我们继续分析每个encoder的详细结构:在Transformerencoder中,数据首先会经过一个叫做‘self-attention’的模块得到一个加权之后的特征向量 Z ,这个Z 便是论文公式1中的  Attention(Q,K,V)

    得到的Z,会被送到encoder的下一个模块,Feed Forward Neural Network,这个全连接有两层,第一层的激活函数是ReLU,第二层是一个线性激活函数,可以表示为:

    Decoder的结构如图5所示,它和encoder的不同之处在于Decoder多了一个Encoder-Decoder Attention,两个Attention分别用于计算输入和输出的权值: 

    1. Self-Attention:当前翻译和已翻译的前文之间的关系;
    2. Encoder-Decnoder Attention:当前翻译和编码的特征向量之间的关系。

    3Transform encoder过程

    首先将词通过word2vec表示为向量,第一层encoder的输入直接为词x的向量表示,而在其他层中,输入则是上一个block的输出。如下图所示:

    4、Attention

    Attention模型并不只是盲目地将输出的第一个单词与输入的第一个词对齐。Attention机制的本质来自于人类视觉注意力机制。人们在看东西的时候一般不会从到头看到尾全部都看,往往只会根据需求观察注意特定的一部分,就是一种权重参数的分配机制,目标是协助模型捕捉重要信息。即给定一组<key,value>,以及一个目标(查询)向量query,attention机制就是通过计算query与每一组key的相似性,得到每个key的权重系数,再通过对value加权求和,得到最终attention数值。

    5、Self-Attention

    5.1、self-Attention细节描述  

    Self-Attention是Transformer最核心的内容,其核心内容是为输入向量的每个单词学习一个权重

    self-attention中,每个单词有3个不同的向量,它们分别是Query向量( Q ),Key向量( K)和Value向量( V ),长度均是64。它们是通过3个不同的权值矩阵由嵌入向量 X 乘以三个不同的权值矩阵 WQWK  WV  得到,其中三个矩阵的尺寸也是相同的。均是 512*64;Q,K,V这些向量的概念是很抽象,但是它确实有助于计算注意力。相较于RNNs,transformer具有更好的并行性。

    1. 如上文,将输入单词转化成嵌入向量;
    2. 根据嵌入向量得到 q ,k,v 三个向量;
    3. 为每个向量计算一个score score=q*k 
    4. 为了梯度的稳定,Transformer使用了score归一化,即除以  sqrt(dk)=8 (论文中使用key向量的维度是64维,其平方根=8,这样可以使得训练过程中具有更稳定的梯度。)
    5. score施以softmax激活函数,使得最后的列表和为1这个softmax的分数决定了当前单词在每个句子中每个单词位置的表示程度。很明显,当前单词对应句子中此单词所在位置的softmax的分数最高,但是,有时候attention机制也能关注到此单词外的其他单词,这很有用。
    6. softmax点乘Value v ,得到加权的每个输入向量的评分 v ;相当于保存对当前词的关注度不变的情况下,降低对不相关词的关注。
    7. 相加之后得到最终的输出结果  ;这会在此位置产生self-attention层的输出(对于第一个单词)。

    5.2、矩阵运算过程描述

    6、Multi-Head Attention  

    Multi-Head Attention相当于 h 个不同的self-attention的集成(ensemble),在这里我们以 h=8 举例说明。Multi-Head Attention的输出分成3步:

       1、将数据 X 分别输入到5章节所示的8self-attention中,得到8个加权后的特征矩阵 

       2、将8个  按列拼成一个大的特征矩阵;前馈神经网络没法输入8个矩阵,所以需要把8个矩阵降为1个,在这里通过把8个矩阵连在一起。

       3、特征矩阵经过一层全连接后得到输出 Z 

    具体过程如下:

    7、Transform的encoder整体结构

    在self-attention需要强调的最后一点是其采用了残差网络 中的short-cut结构,目的当然是解决深度学习中的退化问题。FFN 相当于将每个位置的Attention结果映射到一个更大维度的特征空间,然后使用ReLU引入非线性进行筛选,最后恢复回原始维度。

    8、自注意机制的复杂度

    对于使用自注意力机制的原因,论文中提到主要从三个方面考虑(每一层的复杂度,是否可并行长距离依赖学习),并给出了和RNN,CNN计算复杂度的比较。可以看到,如果输入序列n小于表示维度d的话,每一层的时间复杂度self-attention是比较有优势的。当n比较大时,作者也给出了一种解决方案self-attention(restricted)即每个词不是和所有词计算attention,而是只与限制的r个词去计算attention。在并行方面,多头attention和CNN一样不依赖于前一时刻的计算,可以很好的并行,优于RNN。在长距离依赖上,由于self-attention是每个词和所有词都要计算attention,所以不管他们中间有多长距离,最大的路径长度也都只是1。可以捕获长距离依赖关系。

    9、Positional Encoding

    transformer给encoder层和decoder层的输入添加了一个额外的向量Positional Encoding,维度和embedding的维度一样,这个向量采用了一种很独特的方法来让模型学习到这个值,这个向量能决定当前词的位置,或者说在一个句子中不同的词之间的距离。计算方法如下

    其中pos是指当前词在句子中的位置,i是指向量中每个值的index,可以看出,在偶数位置,使用正弦编码,在奇数位置,使用余弦编码。最后把这个Positional Encoding与embedding的值相加,作为输入送到下一层。

    eg:嵌入维度为4,考虑位置编码的情况如下:

    在这里插入图片描述

    10、残差模块和Layer normalization

    在transformer中,每一个子层(self-attetion,ffnn)之后都会接一个残差模块,并且有一个Layer normalization;

    eg: 2个Encoder和2个Decoder的Transformer:

    10.1、残差引入目的

    随着网络深度的增加,训练变得愈加困难,这主要是因为在基于随机梯度下降的网络训练过程中,误差信号的多层反向传播非常容易引发“梯度弥散”(梯度过小会使回传的训练误差信号极其微弱)或者“梯度爆炸”(梯度过大导致模型出现NaN)的现象。目前一些特殊的权重初始化策略和批规范化(BN)等方法使这个问题得到了极大改善——网络可以正常训练了!! 但是实际情形不容乐观。当模型收敛时,另外的问题又来了:随着网络深度的增加,训练误差没有降低反而升高。 这一现象与直觉极其不符,浅层网络可以被训练优化到一个很好的解,那么对应的更深层的网络至少也可以,而不是更差。这一现象在一段时间内困扰着更深层卷积神经网络的设计、训练和应用。

    残差模块:y=F(x,w)+x
    高速公路网络的“变换门”和“携带门”都为恒等映射时(即令 T=1,C=1T=1,C=1 ),就得到了残差网络

    10.2、Normalization引入目的

    Normalization有很多种,但是它们都有一个共同的目的,那就是把输入转化成均值为0方差为1的数据。我们在把数据送入激活函数之前进行normalization(归一化),因为我们不希望输入数据落在激活函数的饱和区。 Batch Normalization。BN的主要思想就是:在每一层的每一批数据上进行归一化。我们可能会对输入数据进行归一化,但是经过该网络层的作用后,我们的数据已经不再是归一化的了。随着这种情况的发展,数据的偏差越来越大,我的反向传播需要考虑到这些大的偏差,这就迫使我们只能使用较小的学习率来防止梯度消失或者梯度爆炸。

     Layer normalization它也是归一化数据的一种方式,不过 LN 是在每一个样本上计算均值和方差,而每一个特征维度上进行归一化

     

    11、Decoder层

    transform的整体结构如下图所示;在解码器中,Transformer block比编码器中多了个encoder-decoder attention。在encoder-decoder attention中, 来自于解码器的上一个输出,K   V 则来自于与编码器的输出。

    由于在机器翻译中,解码过程是一个顺序操作的过程,也就是当解码第 个特征向量时,我们只能看到第 K-1 及其之前的解码结果,论文中把这种情况下的multi-head attention叫做masked multi-head attention。transfrom的encoder和decoder整体架构如下:

    11.1、Mask

    mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。

    11.2、Padding Mask

    padding mask:因为每个批次输入序列长度是不一样,需要对输入序列进行对齐。给较短的序列后面填充 0,对于输入太长的序列,截取左边的内容,把多余的直接舍弃。这些填充的位置,没什么意义,所以我们的attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。

    具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过 softmax,这些位置的概率就会接近0!

    而我们的 padding mask 实际上是一个张量,每个值都是一个Boolean,值为 false 的地方就是我们要进行处理的地方。

    11.3、Sequence mask

    sequence mask 是为了使得 decoder 不能看见未来的信息。也就是对于一个序列,在 time_step 为 t 的时刻,我们的解码输出应该只能依赖于 t 时刻之前的输出,而不能依赖 t 之后的输出。因此我们需要想一个办法,把 t 之后的信息给隐藏起来。

    具体做法:产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每一个序列上。

    • 对于 decoder 的 self-attention,同时需要padding mask 和 sequence mask 作为 attn_mask,具体实现就是两个mask相加作为attn_mask。
    • 其他情况,attn_mask 一律等于 padding mask。

    eg:

    编码器处理输入序列,最终输出为一组注意向量k和v。每个解码器将在其“encoder-decoder attention”层中使用k,v注意向量,这有助于解码器将注意力集中在输入序列中的适当位置:

    11.4、解码过程

    对于Decoder,和Encoder一样,初始输入为词嵌入+词位置编码;不同在于,self attention只关注输出序列中的较早的位置。在self-attention 计算中的softmax步骤之前屏蔽了特征位置(设置为 -inf)来完成的。encoder-decoder attention过程和self-attention一致,只是其k,v来自于编码器的输出。

    动图可以参考:https://blog.csdn.net/jiaowoshouzi/article/details/89073944

                              https://blog.csdn.net/qq_41664845/article/details/84969266

    12、输出层

             Decoder的输出是浮点数的向量列表。把得到的向量映射为需要的词,需要线性层和softmax层获取预测为词的概率。

             线性层是一个简单的全连接神经网络,它是由Decoder堆栈产生的向量投影到一个更大,更大的向量中,称为对数向量

            假设实验中我们的模型从训练数据集上总共学习到1万个英语单词(“Output Vocabulary”)。这对应的Logits矢量也有1万个长度-每一段表示了一个唯一单词的得分。在线性层之后是一个softmax层,softmax将这些分数转换为概率。选取概率最高的索引,然后通过这个索引找到对应的单词作为输出。

    13、 优缺点总结

    优点

    (1)虽然Transformer最终也没有逃脱传统学习的套路,Transformer也只是一个全连接(或者是一维卷积)加Attention的结合体。但是其设计已经足够有创新,因为其抛弃了在NLP中最根本的RNN或者CNN并且取得了非常不错的效果,算法的设计非常精彩,值得每个深度学习的相关人员仔细研究和品位。

    (2)Transformer的设计最大的带来性能提升的关键是将任意两个单词的距离是1,这对解决NLP中棘手的长期依赖问题是非常有效的。

    (3)Transformer不仅仅可以应用在NLP的机器翻译领域,甚至可以不局限于NLP领域,是非常有科研潜力的一个方向。

    (4)算法的并行性非常好,符合目前的硬件(主要指GPU)环境。

    缺点

    (1)粗暴的抛弃RNN和CNN虽然非常炫技,但是它也使模型丧失了捕捉局部特征的能力,RNN + CNN + Transformer的结合可能会带来更好的效果。

    (2)Transformer失去的位置信息其实在NLP中非常重要,而论文中在特征向量中加入Position Embedding也只是一个权宜之计,并没有改变Transformer结构上的固有缺陷。

     

    参考文章

    https://blog.csdn.net/weixin_44695969/article/details/102997574 (残差网络)

    https://blog.csdn.net/jiaowoshouzi/article/details/89073944 (一文读懂bert,介绍了传统的神经网络模型,及transform详解)

    https://blog.csdn.net/qq_41664845/article/details/84969266 (transform很详细的介绍)

    https://zhuanlan.zhihu.com/p/139595546 (各种mask策略)

    http://jalammar.github.io/illustrated-transformer/ (英文transfrom详解)

    https://zhuanlan.zhihu.com/p/48508221 (transform针对改进点解析的文章)

    https://zhuanlan.zhihu.com/p/60821628 (transform的一些细节优化点详解)

    展开全文
  • imageTransform3D.js

    2015-05-15 00:53:37
    html5实现3D图片效果所用的js脚步文件imageTransform3D.js。html5实现3D图片效果所用的js脚步文件imageTransform3D.js。
  • Gradle Transform 详解

    千次阅读 2019-12-05 10:44:24
    Transform其实可以有两种输入,一种是消费型的,当前Transform需要将消费型型输出给下一个Transform,另一种是引用型的,当前Transform可以读取这些输入,而不需要输出给下一个Transform,比如Instant Run就是通过...

    我们先来看下Android应用程序打包流程:

    通过上图可知,我们只要在图中红色箭头处拦截(生成class文件之后,dex文件之前),就可以拿到当前应用程序中所有的.class文件,再去借助ASM之类的库,就可以遍历这些.class文件中所有方法,再根据一定的条件找到需要的目标方法,最后进行修改并保存,就可以插入我们的埋点代码。

    Google从 Android Gradle 1.5.0 开始,提供了Transform API。通过Transform API,允许第三方以插件的形式,在Android应用程序打包成dex文件之前的编译过程中操作.class文件。我们只要实现一套Transform,去遍历所有.class文件的所有方法,然后进行修改(在特定的listener回调中插入埋点代码),再对源文件进行替换,即可以达到插入代码的目的。

    Gradle Transform概述

    Gradle Transform是Android官方提供给开发者在项目构建阶段(.class -> .dex转换期间)用来修改.class文件的一套标准API,即把输入的.class文件转变成目标字节码文件。目前比较经典的应用是字节码插桩、代码注入等。

    我们build一个项目,会打印出如下日志,红框框住的部分就是一个Transform的名称

    通过上张图可以看到原生就带了一系列Transform供使用,那么这些Transform是怎么组织在一起的呢,我们用一张图表示:

    每个Transform其实都是一个gradle task,Android编译器中的TaskManager将每个Transform串连起来,第一个Transform接收来自javac编译的结果,以及已经拉取到在本地的第三方依赖(jar、aar),还有resource资源,注意,这里的resource并非android项目中的res资源,而是asset目录下的资源。 这些编译的中间产物,在Transform组成的链条上流动,每个Transform节点可以对class进行处理再传递给下一个Transform。我们常见的混淆,Desugar等逻辑,它们的实现如今都是封装在一个个Transform中,而我们自定义的Transform,会插入到这个Transform链条的最前面。

    但其实,上面这幅图,只是展示Transform的其中一种情况。而Transform其实可以有两种输入,一种是消费型的,当前Transform需要将消费型型输出给下一个Transform,另一种是引用型的,当前Transform可以读取这些输入,而不需要输出给下一个Transform,比如Instant Run就是通过这种方式,检查两次编译之间的diff的。

    最终,我们定义的Transform会被转化成一个个TransformTask,在Gradle编译时调用。

    Transform两个基础概念

    • TransformInput
    • TransformOutputProvider

    TransformInput

    TransformInput是指输入文件的一个抽象,包括:

    • DitectoryInput集合
      是指以源码的方式参与项目编译的所有目录结构及其目录下的源码文件

    • JarInput集合
      是指以jar包方式参与项目编译的所有本地jar包和远程jar包(此处的jar包包括aar)

    TransformOutputProvider

    之Transform的输出,通过它可以获取到输出路径等信息

    Transform.java

    先来了解下Transform类,定义如下

    public abstract class Transform {
        public Transform() {
        }
    
        // Transform名称
        public abstract String getName();
    
        public abstract Set<ContentType> getInputTypes();
    
        public Set<ContentType> getOutputTypes() {
            return this.getInputTypes();
        }
    
        public abstract Set<? super Scope> getScopes();
    
    
        public abstract boolean isIncremental();
    
        /** @deprecated */
        @Deprecated
        public void transform(Context context, Collection<TransformInput> inputs, Collection<TransformInput> referencedInputs, TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException {
        }
    
        public void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
            this.transform(transformInvocation.getContext(), transformInvocation.getInputs(), transformInvocation.getReferencedInputs(), transformInvocation.getOutputProvider(), transformInvocation.isIncremental());
        }
    
        public boolean isCacheable() {
            return false;
        }
        
        ...
    }
    
    

    Transform#getName()

    Transform名称,上面build日志红框框住的部分就是Transform名称

    transformClassesWithDexBuilderForDebug
    

    那么最终的名字是如何构成的呢?

    在gradle plugin的源码中有一个叫TransformManager的类,这个类管理着所有的Transform的子类,里面有一个方法叫getTaskNamePrefix,在这个方法中就是获得Task的前缀,以transform开头,之后拼接ContentType,这个ContentType代表着这个Transform的输入文件的类型,类型主要有两种,一种是Classes,另一种是Resources,ContentType之间使用And连接,拼接完成后加上With,之后紧跟的就是这个Transform的Name,name在getName()方法中重写返回即可。TransformManager#getTaskNamePrefix()代码如下:

    static String getTaskNamePrefix(Transform transform) {
            StringBuilder sb = new StringBuilder(100);
            sb.append("transform");
            sb.append((String)transform.getInputTypes().stream().map((inputType) -> {
                return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, inputType.name());
            }).sorted().collect(Collectors.joining("And")));
            sb.append("With");
            StringHelper.appendCapitalized(sb, transform.getName());
            sb.append("For");
            return sb.toString();
        }
    

    Transform#getInputTypes()

    需要处理的数据类型,有两种枚举类型

    • CLASSES
      代表处理的 java 的 class 文件,返回TransformManager.CONTENT_CLASS

    • RESOURCES
      代表要处理 java 的资源,返回TransformManager.CONTENT_RESOURCES

    Transform#getScopes()

    指 Transform 要操作内容的范围,官方文档 Scope 有 7 种类型:

    1. EXTERNAL_LIBRARIES ----------------只有外部库
    2. PROJECT -----------------------------------只有项目内容
    3. PROJECT_LOCAL_DEPS ------------- 只有项目的本地依赖(本地jar)
    4. PROVIDED_ONLY ------------------------只提供本地或远程依赖项
    5. SUB_PROJECTS -------------------------只有子项目
    6. SUB_PROJECTS_LOCAL_DEPS-----只有子项目的本地依赖项(本地jar)
    7. TESTED_CODE ---------------------------由当前变量(包括依赖项)测试的代码
      如果要处理所有的class字节码,返回TransformManager.SCOPE_FULL_PROJECT

    Transform#isIncremental()

    增量编译开关

    当我们开启增量编译的时候,相当input包含了changed/removed/added三种状态,实际上还有notchanged。需要做的操作如下:

    • NOTCHANGED: 当前文件不需处理,甚至复制操作都不用;
    • ADDED、CHANGED: 正常处理,输出给下一个任务;
    • REMOVED: 移除outputProvider获取路径对应的文件。

    Transform#transform()

     public void transform(@NonNull TransformInvocation transformInvocation)
                throws TransformException, InterruptedException, IOException {
            // Just delegate to old method, for code that uses the old API.
            //noinspection deprecation
            this.transform(transformInvocation.getContext(), transformInvocation.getInputs(),
                    transformInvocation.getReferencedInputs(),
                    transformInvocation.getOutputProvider(),
                    transformInvocation.isIncremental());
        }
    

    注意点

    • 如果拿取了getInputs()的输入进行消费,则transform后必须再输出给下一级
    • 如果拿取了getReferencedInputs()的输入,则不应该被transform
    • 是否增量编译要以transformInvocation.isIncremental()为准

    Transform#isCacheable()

    如果我们的transform需要被缓存,则为true,它被TransformTask所用到

    Transform编写模板

    无增量编译

    AspectJTransform.groovy代码如下:

    class AspectJTransform extends Transform {
    
        final String NAME =  "JokerwanTransform"
    
        @Override
        String getName() {
            return NAME
        }
    
        @Override
        Set<QualifiedContent.ContentType> getInputTypes() {
            return TransformManager.CONTENT_CLASS
        }
    
        @Override
        Set<? super QualifiedContent.Scope> getScopes() {
            return TransformManager.SCOPE_FULL_PROJECT
        }
    
        @Override
        boolean isIncremental() {
            return false
        }
    
          @Override
        void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
            super.transform(transformInvocation)
    
            // OutputProvider管理输出路径,如果消费型输入为空,你会发现OutputProvider == null
            TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();
    
            transformInvocation.inputs.each { TransformInput input ->
                input.jarInputs.each { JarInput jarInput ->
                    // 处理Jar
                    processJarInput(jarInput, outputProvider)
                }
    
                input.directoryInputs.each { DirectoryInput directoryInput ->
                    // 处理源码文件
                    processDirectoryInputs(directoryInput, outputProvider)
                }
            }
        }
    
        void processJarInput(JarInput jarInput, TransformOutputProvider outputProvider) {
            File dest = outputProvider.getContentLocation(
                    jarInput.getFile().getAbsolutePath(),
                    jarInput.getContentTypes(),
                    jarInput.getScopes(),
                    Format.JAR)
                    
            // to do some transform
            
            // 将修改过的字节码copy到dest,就可以实现编译期间干预字节码的目的了        
            FileUtils.copyFiley(jarInput.getFile(), dest)
        }
    
        void processDirectoryInputs(DirectoryInput directoryInput, TransformOutputProvider outputProvider) {
            File dest = outputProvider.getContentLocation(directoryInput.getName(),
                    directoryInput.getContentTypes(), directoryInput.getScopes(),
                    Format.DIRECTORY)
            // 建立文件夹        
            FileUtils.forceMkdir(dest)
            
            // to do some transform
            
            // 将修改过的字节码copy到dest,就可以实现编译期间干预字节码的目的了        
            FileUtils.copyDirectory(directoryInput.getFile(), dest)
        }
    }
    

    有增量编译

    AspectJTransform.groovy代码如下:

    class AspectJTransform extends Transform {
    
        final String NAME = "JokerWanTransform"
    
        @Override
        String getName() {
            return NAME
        }
    
        @Override
        Set<QualifiedContent.ContentType> getInputTypes() {
            return TransformManager.CONTENT_CLASS
        }
    
        @Override
        Set<? super QualifiedContent.Scope> getScopes() {
            return TransformManager.SCOPE_FULL_PROJECT
        }
    
        @Override
        boolean isIncremental() {
            return true
        }
    
        @Override
        void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
            super.transform(transformInvocation)
    
            boolean isIncremental = transformInvocation.isIncremental()
    
            // OutputProvider管理输出路径,如果消费型输入为空,你会发现OutputProvider == null
            TransformOutputProvider outputProvider = transformInvocation.getOutputProvider()
    
            if (!isIncremental) {
                // 不需要增量编译,先清除全部
                outputProvider.deleteAll()
            }
    
            transformInvocation.getInputs().each { TransformInput input ->
                input.jarInputs.each { JarInput jarInput ->
                    // 处理Jar
                    processJarInputWithIncremental(jarInput, outputProvider, isIncremental)
                }
    
                input.directoryInputs.each { DirectoryInput directoryInput ->
                    // 处理文件
                    processDirectoryInputWithIncremental(directoryInput, outputProvider, isIncremental)
                }
            }
        }
    
        void processJarInputWithIncremental(JarInput jarInput, TransformOutputProvider outputProvider, boolean isIncremental) {
            File dest = outputProvider.getContentLocation(
                    jarInput.getFile().getAbsolutePath(),
                    jarInput.getContentTypes(),
                    jarInput.getScopes(),
                    Format.JAR)
            if (isIncremental) {
                // 处理增量编译
                processJarInputWhenIncremental(jarInput, dest)
            } else {
                // 不处理增量编译
                processJarInput(jarInput, dest)
            }
        }
    
        void processJarInput(JarInput jarInput, File dest) {
            transformJarInput(jarInput, dest)
        }
    
        void processJarInputWhenIncremental(JarInput jarInput, File dest) {
            switch (jarInput.status) {
                case Status.NOTCHANGED:
                    break
                case Status.ADDED:
                case Status.CHANGED:
                    // 处理有变化的
                    transformJarInputWhenIncremental(jarInput.getFile(), dest, jarInput.status)
                    break
                case Status.REMOVED:
                    // 移除Removed
                    if (dest.exists()) {
                        FileUtils.forceDelete(dest)
                    }
                    break
            }
        }
    
        void transformJarInputWhenIncremental(JarInput jarInput, File dest, Status status) {
            if (status == Status.CHANGED) {
                // Changed的状态需要先删除之前的
                if (dest.exists()) {
                    FileUtils.forceDelete(dest)
                }
            }
            // 真正transform的地方
            transformJarInput(jarInput, dest)
        }
    
        void transformJarInput(JarInput jarInput, File dest) {
        
            // to do some transform
            
            // 将修改过的字节码copy到dest,就可以实现编译期间干预字节码的目的了
            FileUtils.copyFile(jarInput.getFile(), dest)
        }
    
        void processDirectoryInputWithIncremental(DirectoryInput directoryInput, TransformOutputProvider outputProvider, boolean isIncremental) {
            File dest = outputProvider.getContentLocation(
                    directoryInput.getFile().getAbsolutePath(),
                    directoryInput.getContentTypes(),
                    directoryInput.getScopes(),
                    Format.DIRECTORY)
            if (isIncremental) {
                // 处理增量编译
                processDirectoryInputWhenIncremental(directoryInput, dest)
            } else {
                processDirectoryInput(directoryInput, dest)
            }
        }
    
        void processDirectoryInputWhenIncremental(DirectoryInput directoryInput, File dest) {
            FileUtils.forceMkdir(dest)
            String srcDirPath = directoryInput.getFile().getAbsolutePath()
            String destDirPath = dest.getAbsolutePath()
            Map<File, Status> fileStatusMap = directoryInput.getChangedFiles()
            fileStatusMap.each { Map.Entry<File, Status> entry ->
                File inputFile = entry.getKey()
                Status status = entry.getValue()
                String destFilePath = inputFile.getAbsolutePath().replace(srcDirPath, destDirPath)
                File destFile = new File(destFilePath)
                switch (status) {
                    case Status.NOTCHANGED:
                        break
                    case Status.REMOVED:
                        if (destFile.exists()) {
                            FileUtils.forceDelete(destFile)
                        }
                        break
                    case Status.ADDED:
                    case Status.CHANGED:
                        FileUtils.touch(destFile)
                        transformSingleFile(inputFile, destFile, srcDirPath)
                        break
                }
            }
        }
    
        void processDirectoryInput(DirectoryInput directoryInput, File dest) {
            transformDirectoryInput(directoryInput, dest)
        }
    
        void transformDirectoryInput(DirectoryInput directoryInput, File dest) {
        
            // to do some transform
            
            // 将修改过的字节码copy到dest,就可以实现编译期间干预字节码的目的了
            FileUtils.copyDirectory(directoryInput.getFile(), dest)
        }
    
        void transformSingleFile(File inputFile, File destFile, String srcDirPath) {
            FileUtils.copyFile(inputFile, destFile)
        }
    }
    

    参考文章
    https://www.jianshu.com/p/37a5e058830a

    展开全文
  • sklearn:sklearn.preprocessing.StandardScaler函数的fit_transformtransform、inverse_transform简介、使用方法之详细攻略 目录 StandardScaler函数的的简介及其用法 StandardScaler函数的的简介 ...
  • about fourier transform

    2014-05-25 16:00:48
    图像的裁剪 转化 和傅里叶变换 裁剪过后 中心高频的傅里叶变换保留一定的轮廓 周围低频傅里叶变换保留一轮廓
  • CSS3transform属性详解

    万次阅读 2019-05-17 21:43:30
    Transform字面上就是变形,改变的意思。在CSS3中transform主要包括以下几种:旋转rotate、扭曲skew、缩放scale和移动translate以及矩阵变形matrix。下面我们一起来看看CSS3中transform的旋转rotate、扭曲skew、缩放...
  • html,css,js,CSS3,transform实现multi-flip图片轮播动画
  • 引用:Is there a way to destroy/replace a GameObject that is inside or part of a Prefab instance? Changing Transform on a Prefab ...默认Model对象导入Transform组件,但是在ui中有些组件需要RectTransform组.
  • transform的高级用法

    千次阅读 2018-09-15 11:20:31
    前面我们学习了css3的transform属性了,但是总觉得例子不够充分,不够具体,本文就是再次讲解css3的变形(transform)的用法和实例演示。 &nbsp; Transform字面上就是变形,改变的意思。在CSS3中transform主要...
  • transform属性

    千次阅读 2018-07-15 18:23:12
    Transform字面上就是变形,改变的意思。在CSS3中transform主要包括以下几种:旋转rotate、扭曲skew、缩放scale和移动translate以及矩阵变形matrix。下面我们一起来看看CSS3中transform的旋转rotate、扭曲skew、缩放...
  • Unity——RectTransform详解

    千次阅读 多人点赞 2020-04-24 11:08:57
    Unity——RectTransform详解 目录 1.Anchor(Min,Max) 2.绝对与相对布局 3.Pivot 4.Offset(Min,Max) 5.SizeDelta 6.rect 7.anchoredPosition 8.Recttransform类中一些方法的介绍 1. Anchor unity中的ui元素是有严格的...
  • transform实现手风琴

    2017-12-12 14:01:34
    transform实现手风琴.transform实现手风琴.transform实现手风琴.
  • 还不知道transform 3D转换怎么用?看这个就够了
  • fit_transform,fit,transform区别和作用详解!!!!!!

    万次阅读 多人点赞 2018-10-08 18:14:47
    1. 写在前面 fit和transform没有任何关系,仅仅是数据处理的两个不同环节,之所以出来这么个函数名,仅仅是为了写代码方便。...transform函数是一定可以替换为fit_transform函数的,fit_transform函数不能替换为...
  • 今天开始我们一起来学习有关于CSS3制作动画的几个属性:变形(transform)、转换(transition)和动画(animation)等更高级的CSS3技术。本文主要介绍的是这三个属性之中的第一个──变形transformTransform字面上就是...
  • C++/C++11中std::transform的使用

    千次阅读 2019-07-16 08:42:46
    std::transform在指定的范围内应用于给定的操作,并将结果存储在指定的另一个范围内。要使用std::transform函数需要包含<algorithm>头文件。 以下是std::transform的两个声明,一个是对应于一元操作,一个是...
  • Unity中RectTransformtransform的区别

    千次阅读 2020-05-29 16:37:45
    Rect Transform Anchors: 作用: 决定”锚点“在”父物体“中的位置和样式,取值范围为0(父物体左下) - 1(父物体右上)。 当值的最大和最小不相同的时候表示一个区间,这时锚点会散开,锚点的一边在最小值上,...
  • fit,transform,fit_transform详解

    千次阅读 2019-05-24 17:10:02
    fit和transform没有任何关系,仅仅是数据处理的两个不同环节,之所以出来fit_transform这个函数名,仅仅是为了写代码方便,会高效一点。 sklearn里的封装好的各种算法使用前都要fit,fit相对于整个代码而言,为后续...
  • transform(变形)和transform-origin(变形原点)的说明: 目前这两个属性得到了除去ie以外各个主流浏览器webkit,firefox,opera的支持,属性名分别为 -webkit-transform,-moz-transform,-o-tr...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 514,235
精华内容 205,694
关键字:

transform