2019-08-20 11:20:30 weixin_38744526 阅读数 10697

最近在写论文做毕业设计,真是一个头两个大。写过论文的伙伴一定都懂,头发一撮一撮地掉,好心痛!

我的毕设需要用到树莓派编程然后转接到Unity3D利用多媒体投影显示内容,这中间需要用到网络通信多线程。

查了一些资料,决定选择Python Socket来实现功能。Socket是任何一种计算机网络通讯中最基础的内容,网上也能查到好多Python Socket 套接字编程的指南和教程。

不过,教程太多弄得我眼花缭乱,也没明白Socket通信多线程是咋回事,偶然发现了一个讲Python 多线程的小视频,我觉得讲的超详细,很容易懂,特来分享给大家~

如果你也想知道Python多线程是怎么实现的,跟我一起看看下方视频,听知名技术专家李刚老师对Socket多线程和Python的TCP支持与创建TCP服务端的详细解析,

并发编程+网络编程

李刚老师出版的《疯狂java》体系图书曾得到市场的广泛认可,经过多次再版,并被多家高校选作教材。上方视频来自于李刚老师的在线视频课程《21天通关Python》第八章 并发编程+网络编程

鉴于大家都有学习Python的困惑,今天就给大家推荐一本巨有影响力的Python实战书,上线时间仅2个月,就超越了众多实力派,成京东和当当网上的长期畅销图书,并且收获了3.4W的五星好评。

这本书可谓是笔者独家私藏图书之一了,对我学习Python有着莫大的帮助,在京东上也常常"断货",这次拿出来给大家分享一下,希望能帮到大家。

《21天通关Python》视频课程以畅销图书为教材,由图书作者李刚亲自操刀讲解;上手门槛低,可作为0基础掌握Python教材;书籍+线上复合型学习场景特别适合Python小白学习!

点此查看课程:https://edu.csdn.net/bundled/detail/49?utm_source=jiansuopy58_1
(含图书邮寄+视频教程+社群答疑+导师带队)

笔者跟大家分享一个福利!下单时输入优惠码csdn66,立减20元,券后仅需99元
扫码入Python技术交流群,可免费听技术讲座+领学习资料+视频课免费看
在这里插入图片描述

2017-07-11 14:13:13 Mogoson 阅读数 1374

MGS-PathAnimation

概述

Unity3D 制作路径动画 插件包。

需求

  • 创建,编辑路径锚点;
  • 依据路径播放位移动画。

方案

  • 利用AnimationCurve实现基于锚点的平滑路径。

实现

  • 扩展编辑器,辅助创建,编辑路径瞄点;
  • VectorCurve.cs:三维空间动画曲线;
  • Path.cs:依据锚点创建平滑路径;
  • PathAnimation.cs:依据路径播放位移动画。

案例

“MGS-PathAnimation/Scenes”目录下存放简易演示案例,供读者参考。

源码

源码托管地址

2017-02-28 18:33:21 LXL_815520 阅读数 3366

第一部分:介绍

  AnimationCurve是Unity3D里一个非常实用的功能。作用是编辑一条任意变化的曲线用在任何你想用在的地方。 如曲线地形,曲线轨迹等。也被用在了模型动画播放时的碰撞盒缩放及重力调节。AnimationCurve 曲线的绘制方法和Ragespline中的物体轮廓勾勒的方法类似。

第二部分:基本使用

第一步:创建物体
第二步:创建脚本
创建AnimationCurveTutor.cs的脚本并添加到物体上。代码如下。
  1. using UnityEngine;
  2. using System.Collections;
  3. public class AnimationCurveTutor : MonoBehaviour{
  4. public AnimationCurve anim;
  5. }
第三步:绘制曲线
把脚本添加到物体上后,物体的Inspector面板下看到如下界面。

双击上图红色区域即进入曲线编辑界面(下图)。

双击任意区域内地方,创建关键点。对关键点点鼠标邮件,则出如下界面.

基本操作:
创建关键点:左键双击
删除关键点:
(1)鼠标移动至关键点上,右键->Delete Key。
(2)左键单击关键点,然后按键盘上的delete

设置曲线类型:鼠标移动至关键点上,右键->
Auto:根据关键点自动设置曲线。
Free Smooth:统一设置入切线和出切线
Flat:入切线和出切线为水平
Broken:分别设置入切线和出切线

也可以选Left Tangent(入切线)或者Right Tangent(出切线)或者Both Tangents(两切线)。
Free:自由曲线,与Broken效果基本一样。
Linear:线性曲线
Constant:之前一直是上个点的值,然后瞬间变为这个点的值。

其中Auto最简单,Broken调整空间最大。曲线效果以绿线为准。
编辑好一条曲线后,在曲线的左右两端会有一个下拉菜单,点击设置两端各自重复的方式。
Loop:曲线循环

Pingpong: 曲线和该曲线上下翻转后的曲线循环

Clamp:一直为端点的值。

第四步:使用曲线
在上面的脚本里,再添加几行代码,如下
  1. using UnityEngine;
  2. using System.Collections;
  3. public class AnimationCurveTutor : MonoBehaviour {
  4. public AnimationCurve anim;
  5. public void Update()
  6. {
  7. transform.position = new Vector3(Time.time, anim.Evaluate(Time.time), 0);
  8. }
  9. }
运行后,物体会按曲线轨迹向右移动。

第三部分:脚本创建AnimationCurve

AnimationCurve可以理解为2部分。(1)键序列(2)左右循环模式(又作左右包裹模式)

一:键序列

创建键序列:Keyframe[] ks = new Keyframe[3];

曲线中加入键序列:AnimationCurve curve new AnimationCurve(ks);

获取曲线中的键序列:curve[index]  或者 curve.keys[index]

添加单键:curve.Addkey(time,value)

删除单键:curve.RemoveKey(index)
二:左右循环
anim.preWrapMode = WrapMode.Loop;

anim.postWrapMode = WrapMode.Once;

三:键

Keyframe kf = new Keyframe(time,value);

kf.inTangent = 45;

kf.outTangent = 45;


用脚本动态实时创建AnimationCurve。创建如下脚本,拖到任意物体运行即可。
  1. using UnityEngine;
  2. using System.Collections;
  3. public class CreateRuntime : MonoBehaviour {
  4.     public AnimationCurve anim = new AnimationCurve();
  5.     void Start() {
  6.         Keyframe[] ks = new Keyframe[3];
  7.         ks[0] = new Keyframe(00);
  8.         ks[0].inTangent = 0;
  9.         ks[1] = new Keyframe(40);
  10.         ks[1].inTangent = 45;
  11.         ks[2] = new Keyframe(80);
  12.         ks[2].inTangent = 90;
  13.         anim = new AnimationCurve(ks);
  14.     }
  15.     void Update() {
  16.         transform.position = new Vector3(Time.time, anim.Evaluate(Time.time), 0);
  17.     }
  18. }

第四部分:编辑器的AnimationCurve

创建EditorCurves.cs及FollowAnimationCurveMine.cs脚本如下。
使用时,先选中物体,再点击Unity菜单栏Examples->Mine,编辑好曲线后点击Generate Curve,之后运行即可。

 

  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;
  4. public class EditorCurves :EditorWindow {
  5. AnimationCurve curveX = AnimationCurve.Linear(0,0,10,10);
  6. [MenuItem("Examples/Mine")]
  7. static void Init()
  8. {
  9. EditorWindow window = GetWindow(typeof(EditorCurves));
  10. window.position = new Rect(0,300,200,100);
  11.         window.Show();
  12. }
  13. void OnGUI()
  14. {
  15.   curveX = EditorGUI.CurveField(new Rect(3,3,position.width-6,15), "Animation on X", curveX);
  16. if(GUI.Button(new Rect(3,60,position.width-6,30),"Generate Curve"))
  17.             AddCurveToSelectedGameObject();
  18. }
  19. void AddCurveToSelectedGameObject()
  20. {
  21. if(Selection.activeGameObject) {
  22.             FollowAnimationCurveMine comp  = Selection.activeGameObject.AddComponent<FollowAnimationCurveMine>();
  23.             comp.SetCurves(curveX);
  24.         } else {
  25.             Debug.LogError("No Game Object selected for adding an animation curve");
  26.         }
  27. }
  28. }

  1. using UnityEngine;
  2. using System.Collections;

  3. public class FollowAnimationCurveMine : MonoBehaviour {
  4. public AnimationCurve curveX;
  5. public void SetCurves(AnimationCurve tmpCurve)
  6. {
  7. curveX = tmpCurve;
  8. }
  9. void Update () {
  10. if(curveX != null)
  11.     transform.position = new Vector3(1f*Time.time, curveX.Evaluate(Time.time) * 0.3f,0);
  12. }
  13. }

2016-09-14 16:44:46 u013017068 阅读数 1421

做拆装虚拟PC时,了解到:

1.unity里脚本控制动画可运用itween插件,方便且美观

2.3d max里调整视角是鼠标中建/鼠标中键+alt

3.3d max绘制数据线,可直接用样条线,并设置成曲线,通过调整视图可见与否控制曲线形状

4.3dmax导出fbx时需要将样条线转换成可编辑多边形,否则在unity中不可见


制作关键帧动画,调研unity变形动画时,学习到3dmax中可制作路径动画和路径变形动画相关知识:

http://ke.qq.com/webcourse/index.html#course_id=108610&term_id=100115610&taid=308700774508610&vid=x1407dscqlv

1.路径动画指按照设定路径移动,先将路径做出来,制作cube绑定动画到路径上,设置关键帧可设置速度方向,做好后导出fbx,将动画加入,在Unity中修改参数

2.路径变形动画指物体按照路径移动,且物体本身跟随路径发生变化,如龙在空中飞舞,可直接用自带路径变形命令,可unity中不支持播放,选用骨骼动画,对骨骼进行路径约束,对骨骼进行IK骨骼样条,导入Unity中。


2019-12-10 10:59:44 qq_35995691 阅读数 8

之前项目有一个需求,要计算摄像机的运动轨迹,并将该运动轨迹的关键帧进行保存。将这些关键帧进行可视化,就像Unity3D中的Animation面板一样,可以查看每一个关键帧像机的状态。

这里使用了AnimationCurve来对关键帧进行计算和操作,代码如下:


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

/// <summary>
///  相机位置
/// </summary>
public class CameraPositionDatas : MonoBehaviour
{
    /*------------------Variable---------------------------*/
    TimelinedVector3 position = new TimelinedVector3();
    TimelinedQuaternion rotation = new TimelinedQuaternion();
    private List<float> value = new List<float>();

    /*-----------------------------------------------------*/
    /// <summary>
    ///  根据传入的百分比得到Index
    /// </summary>
    /// <param name="number">传入的百分比</param>
    /// <returns></returns>
    private int GetIndex(float percentage)
    {
        int index = (int)percentage;// 转换成为Int型
        float remainder = percentage % 1;// 求出小数部分
        if (index == 0)
        {
            return 0;
        }
        else
        {
            return remainder < 0.5f ? index : index + 1;
        }
    }

    /*---------------增删查改--------------------------*/

    /// <summary>
    ///  添加关键帧
    /// </summary>
    /// <param name="percentage">百分比</param>
    /// <param name="transformObj">需要添加物体数据的Transform</param>
    public void AddTransformDatas(float percentage, Transform transformObj)
    {
        int index = GetIndex(percentage);
        if (value.Contains(index))
        {
            return;
        }
        else
        {
            value.Add(index);
            position.Add(index, transformObj.position);
            rotation.Add(index, transformObj.rotation);
        }
    }

    /// <summary>
    ///  移除关键帧
    /// </summary>
    /// <param name="percentage">百分比</param>
    public void RemoveTransformDatas(float percentage)
    {
        int index = GetIndex(percentage);
        if (position.total.keys.Length == 0)
        {
            return;
        }
        else
        {
            if (value.Contains(index))
            {
                for (int i = 0; i < position.total.keys.Length; i++)
                {
                    if (position.total.keys[i].time == index)
                    {
                        position.Remove(i);
                        rotation.Remove(i);
                    }
                }
                value.Remove(index);
            }
            else
            {
                Debug.Log("没有当前帧");
            }
        }
    }

    /// <summary>
    ///  为Transform进行赋值
    /// </summary>
    /// <param name="percentage">百分比</param>
    /// <param name="transformObj">需要获取数据的物体Transform</param>
    public void GetPositionDatas(float percentage, Transform transformObj)
    {
        int index = GetIndex(percentage);
        if (value.Contains(index))
        {
            for (int i = 0; i < position.total.keys.Length; i++)
            {
                if (position.total.keys[i].time == index)
                {
                    transformObj.position = position.FindPosition(i);
                    transformObj.rotation = rotation.FindQuaternion(i);
                }
            }
        }
        else
        {
            Debug.Log("该帧没有数据");
        }
    }

    /// <summary>
    ///  修改关键帧
    /// </summary>
    /// <param name="percentage"></param>
    public void ChangeTransformDatas(float percentage,Transform transformObj)
    {
        // 获得索引值
        int index = GetIndex(percentage);
        for (int i = 0; i < position.total.keys.Length; i++)
        {
            // 如果要插入的帧前面为0
            if (position.total.keys[i].time == index)
            {
                position.Insert(i, i, transformObj.position);
                rotation.Insert(i, i, transformObj.rotation);
            }
        }
    }

}

/*--------------------------------计算Position------------------------------*/
public class TimelinedVector3
{

    public AnimationCurve x = new AnimationCurve();
    public AnimationCurve y = new AnimationCurve();
    public AnimationCurve z = new AnimationCurve();
    public AnimationCurve total = new AnimationCurve();
    public void Add(int index, Vector3 v)
    {
        x.AddKey(index, v.x);
        y.AddKey(index, v.y);
        z.AddKey(index, v.z);
        total.AddKey(index, 0);
    }
    public void Insert(int leftIndex, int index, Vector3 v)
    {
        x.MoveKey(leftIndex, new Keyframe(index, v.x));
        y.MoveKey(leftIndex, new Keyframe(index, v.y));
        z.MoveKey(leftIndex, new Keyframe(index, v.y));
        total.MoveKey(leftIndex, new Keyframe(index, 0));
    }
    public void Remove(int index)
    {
        x.RemoveKey(index);
        y.RemoveKey(index);
        z.RemoveKey(index);
        total.RemoveKey(index);
    }

    public Vector3 FindPosition(int index)
    {
        return new Vector3(x.keys[index].value, y.keys[index].value, z.keys[index].value);
    }
}

/*------------------------------------------计算Quaternion--------------------------------------*/
public class TimelinedQuaternion
{
    public AnimationCurve x = new AnimationCurve();
    public AnimationCurve y = new AnimationCurve();
    public AnimationCurve z = new AnimationCurve();
    public AnimationCurve w = new AnimationCurve();
    public AnimationCurve total = new AnimationCurve();

    public void Add(int index, Quaternion v)
    {
        x.AddKey(index, v.x);
        y.AddKey(index, v.y);
        z.AddKey(index, v.z);
        w.AddKey(index, v.w);
        total.AddKey(index, 0);
    }

    public void Insert(int leftIndex, int index, Quaternion v)
    {
        x.MoveKey(leftIndex, new Keyframe(index, v.x));
        y.MoveKey(leftIndex, new Keyframe(index, v.y));
        z.MoveKey(leftIndex, new Keyframe(index, v.y));
        w.MoveKey(leftIndex, new Keyframe(index, v.w));
        total.MoveKey(leftIndex, new Keyframe(index, 0));
    }

    public void Remove(int index)
    {
        x.RemoveKey(index);
        y.RemoveKey(index);
        z.RemoveKey(index);
        w.RemoveKey(index);
        total.RemoveKey(index);
    }

    public Quaternion FindQuaternion(int index)
    {

        return new Quaternion(x.keys[index].value, y.keys[index].value, z.keys[index].value, w.keys[index].value);
    }
}

 

没有更多推荐了,返回首页