Unity 学习—— 使用Cinemachine让摄像头沿轨道进行运动并进行机器图片和boxes数据截取

 简介.  整个功能是在Unity里面主摄像头旋转移动的过程中对目标的机器模型进行截取图片和数据集。(unity如果没有cinemachine组件,需要自己去package manager下载安装适合自己的版本。(供自学记录)

一.  通过Cinemachine提供的组件,我们实现让摄像头沿着自定义的轨道进行运动,整个功能的实现由三部分构成。

        ①. 虚拟摄像机(Virtual Camera)

        ②. 轨道路径  (Dolly Track)

        ③. 主摄像头 (Main Camera)

实现方式:将虚拟摄像机和主摄像头与轨道进行绑定,然后沿轨道自动运动。

(1) 点击 GameObject,选择创建空物体(命名 Dolly Track) 屏幕右侧Inspector 界面选择添加CinemachineSmoothPath组件(当设置路径弯曲时会自动平滑),如果选择CinemachinePath的话,路径弯曲可由自己进行调整。

参数介绍:

  • Resolution,表示路径的精细度,值越大 路径间的分段就越多
  • Looped,勾选表示头尾相互连接
  • Waypoints,自定义设置的坐标路径点, Roll是翻转角度 有点类似过山车

 (2)设置主摄像头(Main Camera),选择主摄像头Add Component 为主摄像头添加CinemachineDollyCart 组件和CinemachineBrain组件。

 参数介绍:

  • Path,表示选择的轨道路径,这里我们选择上面创建的Dolly Track 
  • Speed,小车沿轨道运动的路径

(3) 创建虚拟摄像头(Virtual Camera) 点击左上Component 选择CinemachineCinemachineVirtualCamera

 参数介绍:

  • Follow,选择相机跟随的目标,这里选择刚创建的主摄像机(Main Camera)
  • Look At,表示相机的朝向,这里选择要拍摄图片和采集数据的GS8机器,当机器由多部件构成时,可自由选择其中某一部件即可
  • Camera Up,摄像机运动时的朝上坐标,可根据想要的效果选择
  • Enabled,勾选表示开启该功能,一定要勾选 否则相机不会跟着主摄像头一起运动

到此,完成效果图如下:当 Play按钮时,相机会围绕着轨道做匀速运动

 二. 为主摄像机添加截取图片的cs文件,选择Add component 选择写好存放在Assets目录下的cs文件,代码如下:

using UnityEngine;
using System.Collections;

//截图
// Capture frames as a screenshot sequence. Images are
// stored as PNG files in a folder - these can be combined into
// a movie using image utility software (eg, QuickTime Pro).

public class Capture : MonoBehaviour
{
    // The folder to contain our screenshots.
    // If the folder exists we will append numbers to create an empty folder.
    public string folder = "ScreenshotFolder";
    public int frameRate = 30;
    private float videoTime = 0;
    void Start()
    {
        // Set the playback framerate (real time will not relate to game time after this).
        //Time.captureDeltaTime = 1.0f / 10;

        // Create the folder
        System.IO.Directory.CreateDirectory(folder);
    }

    void Update()
    {
        videoTime += Time.deltaTime;
        if (videoTime >= (1f / (float)frameRate))
        {

            // Append filename to folder name (format is '0005 shot.png"')
            string name = string.Format("{0}/{1}.png", folder, videoTime.ToString("0.00"));

            // Capture the screenshot to the specified file.
            ScreenCapture.CaptureScreenshot(name);
        }
    }
}

 三. 选择要拍摄的机器,选择Add component 选择写好存放在Assets目录下的cs文件,代码如下:

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

/*
说明:
    将改脚本挂在需要使用该功能物体上
    运行游戏之后,每次按下Space键就可以保存一次该物体在屏幕上的渲染范围的数据
    保存路径是:项目根目录下面的outdata.json文件
*/

public class ObjectMesh : MonoBehaviour
{
    //需要计算的mesh渲染范围
    private MeshRenderer meshRenderer;

    public int fps = 15;
    private float videoTime = 0;
    

    // Start is called before the first frame update

    private string fileName ="";
    void Awake(){
        fileName = Application.dataPath+"/Outdata.json";
        Debug.Log("像素数据保存路径:"+fileName);
        //初始创建保存数据文件
        if(!System.IO.File.Exists(fileName))
        {
            System.IO.File.Create(fileName);
        }
        //初始找到有效mesh
        this.SearchMeshRender();
    }

    void Update()
    {

        Vector3 screenPoint = Camera.main.WorldToViewportPoint(meshRenderer.transform.position);
        bool onScreen = screenPoint.z > 0 && screenPoint.x > 0 && screenPoint.x < 1 && screenPoint.y > 0 && screenPoint.y < 1;
        videoTime += Time.deltaTime;

        if ((videoTime >= (1f / (float)fps)) && (onScreen))
        {
            StartCoroutine(AppendScreenPixel());
        }


    }
    //查找到有效的meshrender组件
    private void SearchMeshRender(){
        meshRenderer = gameObject.transform.GetComponent<MeshRenderer>();
        if(meshRenderer==null)
        {
            meshRenderer = gameObject.GetComponentInChildren<MeshRenderer>();
        }
    }

    //计算物体的有效渲染像素范围
    private IEnumerator AppendScreenPixel(){

        yield return new WaitForEndOfFrame();


        //获取到该物体在屏幕的左下点
        Vector3 min = Camera.main.WorldToScreenPoint(meshRenderer.bounds.min); 
        //获取到该物体在屏幕的右上点
        Vector3 max = Camera.main.WorldToScreenPoint(meshRenderer.bounds.max); 

        /******************************保存数据格式*******************************/
        PixAreaClass pac = new PixAreaClass();
        pac.height =  (int)(max.y- min.y);
        pac.width =  (int)(max.x-min.x);
        pac.boxxes = new float[]{(int)min.x,(int)min.y, (int)(max.x), (int)max.y};
        pac.time = videoTime.ToString("F");
        //pac.time = System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss.ffff");
        /******************************保存数据格式*******************************/

        string data =  JsonUtility.ToJson(pac);
        //data = String.Format("{0:N2}", data);
        //data = data.ToString("0.00");

        Debug.Log(data);
            //添加数据到文件
        System.IO.File.AppendAllLines(fileName, new List<string> {data});





        /*  截图代码  暂时关闭 用于测试效果
        int width = (int)Mathf.Round(pac.width);

        int height = (int)Mathf.Round(pac.height);

        

        float beginx = (int)min.x;

        float beginy = (int)min.y;

        

        Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);

        //Read the pixels in the Rect starting at 0,0 and ending at the screen's width and height

        

        texture.ReadPixels (new Rect (beginx, beginy, width, height),0,0);

        texture.Apply();
        
        System.IO.File.WriteAllBytes(Application.dataPath+"/"+ videoTime + ".jpg",texture.EncodeToJPG());
        */
    }


}

//数据格式
public class PixAreaClass{
    public int height;
    public int width;
    public float[] boxxes;
    public string time;
}

 注意:cs文件的文件名一定要和里面的类名一致。

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MegaFiers是完整的网格变形,动画和变形系统,包括超过50个修改器,例如弯曲,扭曲,FFD,位移,锥度等等。它们可以以任何组合堆叠,并且可以将任意数量的修改器应用于网格以实现复杂的结果。无论您的想象力如何,物体都可以拉伸,挤压或弯曲变形。或者,当对象在空间中移动时,使用空间扭曲使其自动变形。该套件的其他新增功能包括Point Cache动画支持,动态水波纹和浮动对象系统。 所有变形都可以在编辑器模式和播放模式下工作,因此在构建场景时,可以使用变形器为模型添加多样性。 MegaFiers还是变形TextMeshPro对象(Mesh和现在的UI版本)的理想选择,因此您可以用有趣的方式对文本进行动画处理。并且还可以与ProBuilder一起使用,使您可以直接在Unity中创建更多有趣的关卡。一个新功能是可以使用修改器使Sprite变形。 另一个强大的功能是我们的“网格包裹”系统,该系统允许一个网格被另一个变形和设置动画,使其非常适合服装等。该包裹系统还可以与Unity Blendshapes和蒙皮网格一起使用。 MegaWrap也已被重写为使用Jobs and Burst的速度提高了5倍以上。 MegaFiers用C#编写,并且包含所有源代码,并支持所有同时支持Burst和Jobs的Unity平台。从2019年起兼容所有版本的Unity,并且可以在IOS和Android以及VR和AR平台上使用。 MegaFiers还与所有Unity Rendering管道完全兼容。我们还将为Unity的所有新发行版不断更新资产。如果您有关于修改器的想法,请让我们知道或编写。 还包括先进的花键系统,该系统还允许路径跟随或将花键转换为网格,动态软管系统和用于履带车辆的系统。 更多详情:https://assetstore.unity.com/packages/tools/modeling/megafiers-2-188378#description
以下是使用DOTween插件在Unity中实现摄像机跟随路径运动的示例代码: 1. 首先,您需要安装DOTween插件。您可以在Unity Asset Store中搜索“DOTween”并安装它。 2. 创建一个空对象并将其命名为“CameraPath”。 3. 将路径上的所有点作为子对象添加到“CameraPath”对象中。每个子对象应该包含一个Transform组件,指定该点的位置。 4. 在“CameraPath”对象上添加一个脚本组件,并使用以下代码: ```csharp using UnityEngine; using DG.Tweening; public class CameraPathController : MonoBehaviour { public Transform[] waypoints; // 存储路径上的所有点 public float duration = 10.0f; // 动画持续时间 public Ease easeType = Ease.Linear; // 动画插值类型 void Start() { Camera.main.transform.DOPath(GetWaypoints(), duration, PathType.CatmullRom).SetEase(easeType); // 创建路径动画 } Vector3[] GetWaypoints() { Vector3[] path = new Vector3[waypoints.Length]; // 创建路径数组 for (int i = 0; i < waypoints.Length; i++) // 将路径上的所有点添加到路径数组中 { path[i] = waypoints[i].position; } return path; } } ``` 在此示例中,我们使用DOTween的DOPath方法来创建路径动画。我们将路径上的所有点存储在“waypoints”数组中,并使用GetWaypoints方法将它们转换为一个Vector3数组。我们还可以指定动画的持续时间和插值类型。 5. 将摄像机添加到场景中,并将其设置为“CameraPathController”脚本中使用的摄像机。 6. 运行场景并观察摄像机沿着路径移动的效果。 请注意,您可以根据需要调整路径点的数量和位置,并在“CameraPathController”脚本中调整动画的持续时间和插值类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值